home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / COMMUNIC / 1572B.ZIP / KMT_IBM4.ZIP / MSZIBM.ASM < prev   
Assembly Source File  |  1989-07-11  |  194KB  |  3,830 lines

  1.         NAME    mszibm
  2. ; File MSZIBM.ASM
  3.         page 60,132
  4. ; Terminal emulator module for IBM PC's and compatibles. Emulates Heath-19,
  5. ; VT52, and VT102. Original version done by James Harvey, Indiana Purdue
  6. ; Univ, for MS Kermit 2.27. Taken from there by Joe Doupnik, Utah State Univ
  7. ; for MS Kermit 2.29 et seq.
  8. ; Edit history
  9. ; Last edit 20 Jan 1989
  10. ; 20 Jan 1989 Roll screen when clearing entire screen and cursor is at 0,0.
  11. ; 13 Dec 1988 Save G0 and G1 pointers around screen width change. Add test
  12. ;  to detect and implement char code 9bh as ANSI CSI char ("ESC [").
  13. ; 11 Dec 1988 Version 2.32
  14. ; 29 Nov 1988 Revise detection of Transparent Print on/off to permit multiple
  15. ;  arguments in the escape sequences ESC [ 5/4 i. Arguments are executed in
  16. ;  their order of appearance.
  17. ; 26 Nov 1988 Correct setup of cursor type (block/underline) in atsctyp.
  18. ; 12 Nov 1988 Add ESC [ ? 34 h and l as set (h) and reset (l) which invoke
  19. ;  procedures vtsmac and vtrmac, resp, in file msy.
  20. ; 28 Oct 1988 Let screen scroll up (into rollback buffer) when full screen
  21. ;  erase ESC [ 2 J  is received. Suggested by David Lassner.
  22. ; 9 Oct 1988 Add byte vtemu.vtchset to hold choices for VT102 emulator
  23. ;  character sets (US, UK, or Alternate-ROM). Tnx to Baruch Cochavy [bk].
  24. ;  Thus, bit vsshift3 in vtemu.vtflgop is now unused. Alt-ROM is defined as
  25. ;  changing characters 60h-7ah (accent grave and lower case) to be 80h-9ah.
  26. ; 5 Oct 1988 Add controls to write from right to left, using bit vswdir in
  27. ;  the setup bytes vtemu.vtflgst and vtemu.vtflgop. The concept was invented
  28. ;  by Baruch Cochavy, IIT, Haifa, Israel; the current code is by [jrd].
  29. ;  If vswdir is non-zero writing is done starting on the visual right side.
  30. ;  Procedures direction and vtsclr accomdate most directional details. The
  31. ;  implementation here retains DX and CURSOR as logical values while the
  32. ;  physical screen coordinates are conditioned via proc direction and
  33. ;  several sections of special code. Screen printing is done full width if
  34. ;  writing right to left. Outside mszibm the logical cursor = physical. [jrd]
  35. ; 25 Sept 1988 Absorb ESC * char, ESC + char, and ESC <left curly brace>,
  36. ;  thanks to Terry Kennedy who says the VT102 ROM does this.
  37. ; 24 Sept 1988 Move printer output routines to file msyibm to permit buffering
  38. ;  and flow control.
  39. ; 1 July 1988 Version 2.31
  40. ; 10 June 1988 Add oldscrn to sense changes in physical screen sizes.
  41. ; 29 May 1988 Prevent ESC [ Pn @ (ANSI insert spaces) from wrapping. Tnx to
  42. ;  Brian Holley.
  43. ; 27 April 1988 Stop ESC [ 4 m (underscore) from toggling.
  44. ; 20 March 1988 Add ESC [ 1 2 h/l to control local echoing. Use bit 80h in
  45. ;  ansflgs to preserve state of this bit. [jrd]
  46. ; 9 Feb 1988 Mode line again. Make flags.modflg=0 for off, 1 for on and owned
  47. ;  by Kermit, and 2 for on and owned by remote host (toggling suppressed).
  48. ; 25 Jan 1988 Add global byte SCROLL to tell msy routines how many lines
  49. ;  to scroll. This speeds insert/delete line operations. [jrd]
  50. ; 6 Jan 1988 Remove erasing into mode line on to-end-of-screen calls. [jrd]
  51. ; 1 Jan 1988 version 2.30
  52. ;    [Joe R. Doupnik, Utah State Univ]
  53. ;
  54.  
  55.         public  anstty, ansini, ansrei, ansdsl, anstat, anskbi ; Entry points
  56.         public  ans52t, vclick, vsinit
  57.         public  mar_top, mar_bot, anspflg, scroll       ; data for msyibm
  58.         include mssdef.h
  59.  
  60. ; * Disclaimer *
  61. ;
  62. ; DEC and VT are trademarks of Digital Equipment Corporation.
  63. ;
  64. ; There is a naming convention
  65. ; for the ANSI and VT100 functions and flags; generally, the stuff in the
  66. ; symbol after "ans" or "at" is the function or mode mnemonic used in the
  67. ; VT100 manual.
  68. ;
  69. ; Every effort has been made to make the VT100 emulation as much like the
  70. ; real thing as possible.   The reference used was the VT100 User's Guide, 2nd
  71. ; ed. Jan. 1979, DEC part no. EK-VT100-UG.    Some aspects of the behavior
  72. ; of the terminal (e.g., the interaction of the "origin mode", limited
  73. ; scrolling region, and indexing), were gleaned from programming experiments
  74. ; on an actual VT100 terminal.  Implemented features include: (1) Limited
  75. ; scolling region, (2) Settable tab stops, (3) Special "graphics" character
  76. ; set and UK ASII set, (4) All graphic renditions (underline, blink, and
  77. ; high intensity), (5) Simulated "LEDs" on the mode line, (6) Screen mode
  78. ; (normal or reverse video), (7) All terminal reports (status, active position,
  79. ; terminal parameters, and device attributes), (8) The ANSI new-line mode and
  80. ; several of the DEC private modes, including keypad application, cursor key,
  81. ; screen, auto-wrap, and origin, (9) cursor position/graphic rendition/
  82. ; character set save/restore, and last (and probably least): (10) VT52 com-
  83. ; patibility mode.    Also, various details of behavior required by the ANSI
  84. ; standard (e.g. most control characters do not affect the interpretation of
  85. ; the current escape sequence, relative cursor positioning (up, down, left
  86. ; right, and of course tab) stop at the screen margins, etc.) have been
  87. ; scrupulously observed.
  88. ;
  89. ; This was the first thing I ever wrote in 8088 assembler (some of it was
  90. ; stolen from MSYIBM), and one of the constraints was that the emulator
  91. ; should work with a vanilla PC with a monochrome monitor. Given these and
  92. ; other constraints, no attempt was made to implement the following VT100
  93. ; features: (1) Smooth scolling, (2) 132 column lines, (3) Auto repeat,
  94. ; (5) Interlace/no interlace, (6) Double-width/double-height lines. The
  95. ; escape sequences to set and reset these are recognized, but ignored.
  96. ;
  97. ;       - James A. Harvey, IUPUI Computing Services, DEC Systems Group
  98. ;
  99. ; * End of Disclamer *
  100. ; ---------------------------------------------------------------------------
  101. ;
  102. ; Description of the global entry points and calls on external routines
  103. ; needed by this emulator.                                      [jrd]
  104. ;
  105. ; vsinit - start up routine called as Kermit initializes. Takes no arguments.
  106. ;          Sets up address pointers to tabs, reads default terminal parameters
  107. ;          reads current screen coloring. Examines and updates structure
  108. ;          "vtemu." which is how mssset communicates changed information
  109. ;          about many Set Term parameters; "flags." is a Kermit structure
  110. ;          carrying the other Set Term parameters.
  111. ; anstty - starting point for displaying a character, delivered in AL.
  112. ;          Returns when the display operation is completed and that may
  113. ;          take many many instructions. All normal "characters received by
  114. ;          the terminal" are provided by calling anstty with the char in AL.
  115. ; ansini - entry point to initialize the emulator. It requires information
  116. ;          from msy in four registers: the Kermit terminal routine flags
  117. ;          "yflags" (used mainly to sense debug mode and the mode line toggle)
  118. ;          "low_rgt" (bh = row, bl = column of the lower right display corner)
  119. ;          "lbaudtab" (index into baud rate table, for status reporting)
  120. ;          "lpartab" (index into parity table, for status reporting)
  121. ;          Ansini causes a full reset of the emulator, including screen
  122. ;          clearing and a beep. Ansini is also called by msy in response to
  123. ;          sensing the Alt = key combination to fully reset the emulator.
  124. ; ansrei - entry point to reinitialize the emulator. Nearly the same as
  125. ;          ansini except operating flags, tabs, etc are retained from the
  126. ;          previous emulator session. Items which can be changed by Set Term
  127. ;          are examined and updated. The msy flags "yflags" are needed.
  128. ;          This is the warm-restart entry point used when connect mode
  129. ;          is reentered gracefully. The screen is cleared only if the coloring
  130. ;          has changed. The starting cursor location is whereever msy puts it.
  131. ; ansdsl - display "led" (status line) information. Invoked by msy when
  132. ;          the mode line is constructed so the emulator can write the
  133. ;          terminal type and the VT100 led status lights when Connect mode
  134. ;          is started. Requires "yflags" from msy to sense whether the mode
  135. ;          line is to be shown.
  136. ; anstat - reports our working flags and screen coloring to msy. Nearly
  137. ;          obselete but not quite. Reads msy "yflags" and reports "mlbattr"
  138. ;          the video attributes used on the mode line, "scbattr" the video
  139. ;          attributes of an empty character cell (background), "curattr"
  140. ;          the video attributes of displayable characters, and "ansflgs"
  141. ;          the emulator's working flags (needed for keyboard translations
  142. ;          done in msy).
  143. ; anskbi - a routine called by msy to notify the emulator that a character
  144. ;          is available from the keyboard. No character is read, just flag
  145. ;          ttkbi is set. This is actually used only to beep when the cursor
  146. ;          goes beyond column 72 and the margin bell flag is on.
  147. ; ans52t - called by msy to change terminal types "on the fly" without
  148. ;          fully updating all operating parameters and without losing setup
  149. ;          information. Msy senses the Alt minus key and calls ans52t with
  150. ;          no arguments. Ans52t cycles among VT102, VT52 and Heath-19 modes.
  151. ; vclick - called by msy to cause a click sound. Simulates keyboard clicks,
  152. ;          sort of anyway. No arguments.
  153. ; other modules in msy are called by this file to handle screen scrolling
  154. ;          mode line on/off, output to the serial port (reports), screen
  155. ;          particulars (location, cursor shape, blanking). The list is
  156. ;          the set of code extrn procedures below; all are in file msy.
  157. ;
  158. ; data exchange is directly with msy to assist in scrolling (varaibles
  159. ;          "mar_top", "mar_bot") and in sensing the non-connect
  160. ;          mode screen coloring ("scbattr"). Screen coloring controlled by
  161. ;          the emulator is not permitted to influence the non-connect mode
  162. ;          screens whereas the emulator attempts to use the regular Kermit
  163. ;          screen colors as defaults. The kind of terminal to emulate is
  164. ;          held in byte "flags.vtflg" which is set by Set Term and by this
  165. ;          module for global information within Kermit.
  166. ;
  167. ; The emulator assumes the screen is laid out in the manner of a conventional
  168. ;          IBM monochrome or color graphics adapter running in 80 column TEXT
  169. ;          modes. That layout is one word per displayable location starting at
  170. ;          the upper left corner (0,0) and running contiguously to the lower
  171. ;          right corner (24,79). Each word holds the displayable character in
  172. ;          the low order byte and the display attributes in the high order
  173. ;          byte. Attributes are, from high to low bits: blinking on, back-
  174. ;          ground red, green, and blue on, high intensity, foreground red,
  175. ;          green, and blue on. Normal white chars on a black field is 07H.
  176. ;          The starting segment of screen memory is given by msy module
  177. ;          "scrseg" to be TopView/MS Windows compatible. Msy module "scrsync"
  178. ;          is used to inform these windowing environments of memory updates.
  179. ;          Variable "crt_mode" is set by msy to indicate which IBM display
  180. ;          mode is active; only the monochrome and CGA modes are recognized.
  181. ;          Direct reading and writing of display memory is done, compatibly
  182. ;          with TopView/Windows, to attain speed over Bios and DOS calls
  183. ;          when editing of previously entered text is needed. However, IBM
  184. ;          Bios interrupt 10H is used where possible for normal cursor
  185. ;          movement/sensing and writing of new characters. See the IBM PC
  186. ;          hardware Technical Reference Manuals for further details.
  187. ;
  188. ; Many things have been added, or modified since James Harvey donated this
  189. ;          code to Columbia University for use in Kermit.              [jrd]
  190. ; ---------------------------------------------------------------------------
  191.  
  192. screen  equ     10h                     ; Bios screen call
  193. swidth  equ     132                     ; assumed max screen width [dlk]
  194. slen    equ     60                      ; assumed max screen length [jrd]
  195.  
  196. att_low_mask    equ     06H             ; Various attribute-related equates
  197. ;;;att_reverse  equ     70H             ; these two are now storable items
  198. ;;;att_normal   equ     07H             ; to allow external settings. [jrd]
  199. att_underline   equ     01H
  200. att_intensity   equ     08H
  201. att_blink       equ     80H
  202.  
  203. ; VT100 status flags ansflg
  204.  
  205. ;anslnm  equ     01H                     ; ANSI line feed/new line mode
  206. ;decckm  equ     02H                     ; VT100 cursor keys mode
  207. ;deckpam equ     04H                     ; VT100 keypad application mode
  208. ;decscnm equ     08H                     ; VT100 screen mode (n.y.i.)
  209. ;decom   equ     10H                     ; VT100 origin mode
  210. ;decawm  equ     20H                     ; VT100 autowrap mode
  211. ;decanm  equ     40H                     ; ANSI(VT100)/VT52 mode
  212. ;dececho equ     80H                     ; ANSI local echo on (1)
  213.  
  214. ;;;;;;;;;;;;;;;; items for reference from mssdef.h ;;;;;;;;;;;;;
  215.  
  216. ; VT100 SETUP mode flags
  217. ;vswdir          equ     80H             ; Writing direction (0=left to right)
  218. ;vsscreen        equ     40H             ; Screen mode (0 = normal video)
  219. ;vscursor        equ     20H             ; Cursor (0 = block)
  220. ;vsmarginbell    equ     10H             ; Margin bell (0 = off)
  221. ;vskeyclick      equ     08H             ; Keyclick (0 = off)
  222. ;vsshift3        equ     04H             ; Shift-3 (0 = American pound sign)
  223. ;vswrap          equ     02H             ; Line wrap around (0 = no wrap)
  224. ;vsnewline       equ     01H             ; ANSI new line (0 = off)
  225.  
  226. ;vsdefaults      equ     0+vscursor
  227.  
  228. ;[IU1] Definitions for terminal emulation
  229. ;TTGENRC EQU    0               ; Type 0 - TTY (no special emulation)
  230. ;TTHEATH EQU    1               ; Type 1 - HEATH 19
  231. ;TTVT52 EQU     2               ; Type 2 - VT52
  232. ;TTVT100 EQU    3               ; Type 3 - ANSI (VT100 subset)
  233. ;TTTEK  EQU     4               ; Type 4: Tektronix 4010
  234. ;TTTYPES equ    5               ; Number of terminal types defined
  235.  
  236. ;emulst struc           ; structure of vtemu.xxx for VT100 emulator
  237. ;vtflgst db     0       ; VT100 setup flags (from SET)
  238. ;vtflgop db     0       ; VT100 runtime flags, like setup flags (here & STAT)
  239. ;vttbs  dw      0       ; pointer to default tab stops, for SET
  240. ;vttbst dw      0       ; pointer to active tab stops, for STATUS
  241. ;vtchset db     1       ; value of default character set (1=US-ascii)
  242. ;att_ptr dw     0       ; pointer to normal & reverse video attributes
  243. ;emulst ends
  244. ;;;;;;;;;;;;;;;;  end references ;;;;;;;;;;;;;;;;;;;;
  245.  
  246. datas   segment public 'datas'
  247.         extrn vtemu:byte, crt_mode:byte, scbattr:byte, flags:byte
  248.         extrn crt_lins:byte, crt_cols:byte, rxtable:byte, denyflg:word
  249.         extrn tekflg:byte
  250.  
  251. ; Early versions of MASM have a bug that causes it to consider the
  252. ; expression (offset foo) as non-relocatable if used in an arithmetic
  253. ; operation (for example, "sub di,offset foo"), and if foo is defined
  254. ; within the first 256 bytes of the data segment.
  255.  
  256.  
  257. ; ANSI special character table - 32 entries indexed by control char value
  258.  
  259. ansspc  dw      5 dup (atign)           ; ignore NUL,SOH,STX,ETX,EOT
  260.         dw      atign                   ; ENQ - answerback message
  261.         dw      atign                   ; ACK - ignore
  262.         dw      atbel                   ; BEL - ring terminal bell
  263.         dw      atbs                    ; BS - ANSI backspace
  264.         dw      atht                    ; HT - ANSI tab
  265.         dw      atlf                    ; LF - ANSI line feed
  266.         dw      atlf                    ; VT - Interpreted as ANSI LF
  267.         dw      atff                    ; FF - do as LF (but ESC FF does Tek)
  268.         dw      atcr                    ; CR - ANSI carriage-return
  269.         dw      atso                    ; SO - Select char set G1
  270.         dw      atsi                    ; SI - Select char set G0
  271.         dw      8 DUP (atign)   ; ignore DLE,DC1,DC2,DC3,DE4,NAK,SYN,ETB
  272.         dw      atcan                   ; CAN - cancel ANSI sequence
  273.         dw      atign                   ; EM - ignore
  274.         dw      atcan                   ; SUB - treat as CAN
  275.         dw      atesc                   ; ESC - ANSI CSI
  276.         dw      4 DUP (atign)           ; ignore FS,GS,RS,US
  277.  
  278. ; Heath-19 mode escape follower table
  279.  
  280. h19esc  db      'YABCD', 'KIHJF', 'G=><Z', 'ELM'
  281.         db      'NO@p', 'qvwjk', 'xynz', 'blor'
  282. lh19esc equ     $-h19esc
  283.  
  284. ; Dispatch table for Heath-19 escape sequence table h19esc.
  285. ; Two byte sequences of the form ESC char, where char is not in the
  286. ; table above, are completely ignored.
  287.  
  288. h19ejt  dw      v52pos,atcuu,h19cud,h19cuf,atbs         ; 'YABCD'
  289.         dw      atel,atri,atcup,ated,v52egm             ; 'KIHJF'
  290.         dw      v52xgm,atkpam,atkpnm,h19ans,decid       ; 'G=><Z'
  291.         dw      h19clrs,inslin,dellin                   ; 'ELM'
  292.         dw      atdelc,noins,entins,h19herv             ; 'NO@p'
  293.         dw      h19hxrv,h19wrap,h19nowrp,atsc,atrc      ; 'qvwjk'
  294.         dw      h19smod,h19cmod,hrcup,atreset           ; 'xynz'
  295.         dw      h19erb,h19erl,h19ero,h19mbr             ; 'blor'
  296.  
  297. ; Heath-19 special graphics characters. Use as offsets from caret (94D)
  298.  
  299. hgrtab  db      249,17,179,196,197      ; caret,underscore,accent grave,a,b
  300.         db      191,217,192,218,241     ; c,d,e,f,g
  301.         db      26,219,246,25,220       ; h,i,j,k,l
  302.         db      220,223,223,223,222     ; m,n,o,p,q
  303.         db      16,203,185,202,204      ; r,s,t,u,v
  304.         db      'X','/','\','-','-'     ; w,x,y,z,{
  305.         db      221,222,20              ; |,},%
  306.  
  307. ; VT52 compatibility mode escape follower table
  308.  
  309. v52esc  db      'Y','A','B','C','D'
  310.         db      'K','I','H','J','F'
  311.         db      'G','=','>','<','Z'
  312.         db      '7','8','c','~','_'
  313.         db      'W','X',']','V'
  314. lv52esc equ     $-v52esc                ; length of table
  315.  
  316. ; Dispatch for v52esc table
  317.  
  318. v52ejt  dw      v52pos,atcuu,atcud,atcuf,atcub
  319.         dw      atel,atri,atcup,ated,v52egm
  320.         dw      v52xgm,atkpam,atkpnm,v52ans,decid
  321.         dw      atsc,atrc,v52ris,v52apb,v52ape
  322.         dw      v52pcb,v52pce,v52ps,v52pl
  323.  
  324. ; ANSI escape special character table
  325.  
  326. ansesc  db      '[','D','E','M','H'
  327.         db      '7','8','=','>','c'
  328.         db      '(',')','#','Z','<'
  329.         db      'P','*','+',7bh         ; 7bh is left curly brace
  330. lansesc equ     $-ansesc                ; length of table
  331.  
  332. ; Dispatch for ansesc table
  333.  
  334. ansejt  dw      atcsi,atind,atnel,atri,athts
  335.         dw      atsc,atrc,atkpam,atkpnm,atris
  336.         dw      atsg0,atsg1,atsdhl,at52id,atnorm
  337.         dw      atpriv,atpriv,atpriv,atnorm
  338.  
  339.  
  340. ; Final char table for ANSI escape sequences (ESC [ Pn ; ... Pm ch)
  341.  
  342. anstab  db      'H','A','B','C','D'
  343.         db      'K','J','m','g','r'
  344.         db      'c','q','x','n','f'
  345.         db      'l','h','y','P','L'
  346.         db      'M','i','s','u','z'
  347.         db      '@'
  348. lanstab equ     $-anstab                ; Define table length
  349.  
  350. ; Dispatch for anstab table
  351.  
  352. ansjmp  dw      atcup,atcuu,atcud,atcuf,atcub
  353.         dw      atel,ated,atsgr,attbc,atstbm
  354.         dw      atda,atll,atreqt,atdsr,atcup
  355.         dw      atrm,atsm,atctst,atdelc,inslin
  356.         dw      dellin,ansprt,htsc,htrc,htrest
  357.         dw      ansich
  358.  
  359. ; "Special graphics" set translation table for characters 137 (octal)
  360. ; through 176 when the special graphics set is selected.  Some characters
  361. ; (142, 143, 144, 145, 150, 151, 157, 160, 162, 163, and 174) do not
  362. ; have exact equivalents in the available set on the IBM, so a (some-
  363. ; times reasonably close) substitution is made.  Table is indexed by
  364. ; ASCII char value minus 137 octal for chars 137-176 octal.
  365.  
  366. sgrtab  db      032,004,177,026,023
  367.         db      027,025,248,241,021
  368.         db      018,217,191,218,192
  369.         db      197,196,196,196,196
  370.         db      196,195,180,193,194
  371.         db      179,243,242,227,157
  372.         db      156,250
  373.  
  374. ; Device attributes response string. (Note: If "with AVO" causes problems,
  375. ; change the last parameter from "2" to "0". The default is to indicate
  376. ; the AVO option is present because the emulator can set all of the graphic
  377. ; rendition attributes (bold, blink, etc.) independently). A VT100 reports
  378. ; as ESC [ ? 1 ; 2 c  but a VT102 uses ESC [ ? 6 ; 2 c.
  379.  
  380. ;;;dastr        db      escape,'[?6;2c',0               ; VT102
  381. dastr   db      escape,'[?6c',0         ; shortened to help some mainframes
  382.         db      5 dup (0)               ; patch space
  383.  
  384. ; Identify response used while in VT52 compatibility mode
  385. v52str  db      escape,'/Z',0
  386.         db      5 dup (0)               ; patch space
  387.  
  388. ; Identify response when a Heath-19 terminal
  389. h19str  db      escape,'/K',0
  390.         db      5 dup (0)               ; patch space
  391.  
  392. ; ANSI Escape sequence to turn off Media Copy (Print Controller Off)
  393.  
  394. mcoffs  db      24 dup (0)              ; received chars in sequence
  395. mccnt   dw      0                       ; counter of matched char in mcoff
  396.  
  397. ; Parity code translation table
  398.  
  399. partab  db      5                       ; Even
  400.         db      3                       ; Mark
  401.         db      1                       ; None
  402.         db      4                       ; Odd
  403.         db      2                       ; Space
  404. lpartab equ     $-partab
  405.  
  406. ; Baud rate code translation table
  407.  
  408. baudtab db      0                       ; 45.5 - no VT100 code (call it 50)
  409.         db      0                       ; 50
  410.         db      8                       ; 75
  411.         db      16                      ; 110
  412.         db      24                      ; 134.5
  413.         db      32                      ; 150
  414.         db      48                      ; 300
  415.         db      56                      ; 600
  416.         db      64                      ; 1200
  417.         db      72                      ; 1800
  418.         db      80                      ; 2000
  419.         db      88                      ; 2400
  420.         db      104                     ; 4800
  421.         db      112                     ; 9600
  422.         db      120                     ; 19200
  423.         db      128                     ; 38400  extended beyond DEC
  424. lbaudtab        equ     $-baudtab
  425.  
  426. belcol  db      ?                       ; column at which to ring margin bell
  427. yflags  db      ?                       ; Flags from MSYxxx term routine
  428. oldbatr db      ?                       ; old scbattr
  429. oldterm db      ?                       ; terminal type from previous entry
  430. escdec  db      0                       ; DEC private sequence (ESC [ ?) seen
  431. decmode equ     80H                     ; "?" seen in lead-in
  432. baudidx db      ?                       ; Index into baud rate table
  433. parcode db      ?                       ; Parity code (0-4)
  434. datbits db      ?                       ; Number of databits (7 or 8)
  435. savflgs db      ?                       ; Saved flags for atsc/atrc
  436. modeset db      ?                       ; Temp for atsm/atrm
  437. h19mod  db      ?                       ; flag for atsm/atrm
  438. h19l25  db      ?                       ; Heath-19 25th line enabled flag
  439. insmod  db      ?                       ; Insert mode on (1) or off (0)
  440. kbicsr  dw      ?                       ; Cursor when keyboard input typed
  441. kbiflg  db      ?                       ; Set/reset for keyboard input
  442. ttstate dw      offset atnrm            ; terminal automata state
  443.  
  444.                                         ; Start of stuff to save for ESC 7 fxn
  445. ukset   equ     0                       ; Set 1 = UK ASCII set
  446. ascset  equ     1                       ; Set 2 = US ASCII set
  447. sgrset  equ     2                       ; Set 3 = "Special graphics set"
  448. alcset  equ     3                       ; Set 4 = "Alt. Character Set" [bk]
  449. svattr_index    equ 0                   ; To set saved cursor attribute only
  450.  
  451. curattr db      07h                     ; Cursor attribute
  452. cursor  dw      0                       ; Cursor position
  453. video_state db  0                       ; video state (0=normal,1=reversed)
  454. chr_set dw      offset chr_sg0          ; Ptr. to currently selected char set
  455. chr_sg0 db      ascset                  ; Current SG0 set
  456. chr_sg1 db      ascset                  ; Current SG1 set
  457. lsavecu equ     $-curattr               ; Length of stuff to save
  458.  
  459. savecu  db      lsavecu dup (?)         ; Saved cursor, attr., charset, etc
  460. h19ctyp db      1                       ; H-19 cursor type (1=ul, 2=bk, 4=off)
  461.  
  462. att_normal      db      07H             ; retain order: normal then reverse
  463. att_reverse     db      70H
  464.  
  465. mlbattr db      ?                       ; Mode line background attribute
  466.  
  467. ansflgs db      0                       ; ANSI/VT100 mode flags
  468. ; (flags are defined in mssdefs.h)
  469.  
  470. vtflags db      0                       ; VT100 SETUP flags
  471. ; (SETUP flags are defined in mssdefs.h)
  472. tmpflags        db      0               ; (Temporary for asnrei/stblmds)
  473.  
  474. ; (tab stops are stored here)
  475. tabs    db      swidth dup (?)          ; active tab stops
  476. deftabs db      swidth dup (?)          ; default tab stops
  477. vttabs  dw      0                       ; Pointer to default VT100 tab stops
  478.  
  479. ; byte per line, type of line: 0=normal, 1=double wide, 2=double high
  480. linetype db     slen dup (0)
  481.  
  482. linelen db      79                      ; active screen line length (79, 131)
  483. low_rgt dw      0                       ; text screen dimensions
  484.                                         ; byte low_rgt = max columns (79)
  485.                                         ; byte low_rgt+1 = max rows (23)
  486. oldscrn dw      0                       ; old screen. hi=rows-1, low=cols-1
  487. ttkbi   db      0                       ; Flag for keyboard input seen
  488.  
  489. ; Scrolling region - do not separate or change order of mar_top & mar_bot
  490. mar_top db      ?                       ; Scrolling region top margin
  491. mar_bot db      ?                       ; Scrolling region bottom margin
  492. scroll  db      1                       ; lines to scroll
  493.  
  494. led_col equ     65                      ; column position for "LEDs" display
  495. led_off equ     '.'                     ; "Off" LED
  496. ansleds db      'VT102 ....'            ; "LEDs".Terminal ident (10 bytes)
  497. v52leds db      '   VT52   '            ; This is used in VT52 mode
  498. h19leds db      ' Heath-19 '            ; For Heath-19 mode
  499. nansarg db      0                       ; Index for ANSI argument list
  500. ansargs db      16 dup (0)              ; Room for 16 ANSI arguments
  501. lansarg equ     $-ansargs               ; Max number of ANSI arguments
  502.                                         ; printer support data
  503. anspflg db      0                       ; printer flag bits and definitions
  504. vtautop equ     1                       ; autoprint enabled (1)
  505. vtcntp  equ     2                       ; controller print enabled (1)
  506. vtextp  equ     4                       ; printer extent set (1)
  507. vtffp   equ     8                       ; form feed wanted at end of print (1)
  508. datas   ends
  509.  
  510.  
  511. code    segment public 'code'
  512.         extrn   prtbout:near, prtnout:near, csrtype:near, trnmod:near
  513.         extrn   scrmod:near, scrseg:near, scrsync:near, scroff:near
  514.         extrn   scron:near, atsclr:near, vtscru:near, vtscrd:near
  515.         extrn   modwrt:near, telmsy:near, scrloc:near, pcwait:near
  516.         extrn   chgdsp:near, trnprs:near, cptchr:near, tekesc:near
  517.         extrn   pntchr:near, pntchk:near, pntflsh:near
  518.                                 ; extrn procedures are all in module msyibm
  519.         extrn   tekini:near, tekemu:near, tekend:near, vtrmac:near,vtsmac:near
  520.  
  521.         assume  cs:code, ds:datas, es:datas
  522.  
  523. ; This routine initializes the VT100 setups at startup.  It is called from
  524. ; procedure lclyini in module msyibm.
  525.  
  526. vsinit  proc    near
  527.         mov     vtemu.vtflgst,vsdefaults ; Init to defaults in mssdef.h
  528.         mov     vtemu.vtflgop,vsdefaults ; Init runtime state to setup items
  529.         mov     insmod,0                ; turn off insert mode
  530.         mov     deftabs,0               ; Column 1 has no tab stop
  531.         mov     ansflgs,0
  532.         mov     cl,crt_cols             ; physical screen width (80)
  533.         dec     cl                      ; we count from column 0
  534.         mov     ch,crt_lins             ; physical screen length-1
  535.         dec     ch                      ; we count from row 0
  536.         mov     low_rgt,cx              ; store active text area
  537.         mov     cx,131
  538.         mov     di,1                    ; Starting index for column 2
  539. vsini1: mov     al,0                    ; Assume we will clear this one
  540.         test    di,0007H                ; Index mod 8 equals 0?
  541.         jnz     vsini2                  ; No, clear it
  542.         mov     al,0FFH                 ; Yes, set it
  543. vsini2: mov     deftabs[di],al          ; Set or clear a tab stop
  544.         inc     di                      ; Advance to next
  545.         loop    vsini1                  ; Loop for all
  546.         mov     cx,slen                 ; clear linetype array
  547.         mov     di,0
  548. vsini3: mov     linetype[di],0
  549.         inc     di
  550.         loop    vsini3
  551.         mov     vtemu.vttbst,offset deftabs ; addrs of active tabs for STATUS
  552.         mov     vtemu.vttbs,offset deftabs  ; addrs of tabs for setup (SET)
  553.         mov     vttabs,offset deftabs   ; initial source of tabs
  554.         call    cpytabs                 ; copy default to active
  555.         mov     vtemu.att_ptr,offset att_normal  ; ptr to video attributes
  556.         mov     ah,8                    ; read current attributes
  557.         xor     bh,bh                   ; page 0
  558.         int     screen
  559.         mov     scbattr,ah              ; save video attributes
  560.         mov     att_normal,ah           ; set att_normal to present colors
  561.         call    brkatt                  ; separate colors from blink/bold
  562.         rol     ah,1                    ; reverse foreground & background
  563.         rol     ah,1                    ; RGB bits
  564.         rol     ah,1
  565.         rol     ah,1
  566.         call    addatt                  ; reinsert bold/blink bits
  567.         mov     att_reverse,ah          ; set att_reverse too
  568.         mov     ah,byte ptr low_rgt     ; right most column (counted from 0)
  569.         sub     ah,8                    ; place marker 9 columns from margin
  570.         mov     belcol,ah               ; store column number to ring bell
  571.         ret                             ; And return
  572. vsinit  endp
  573.  
  574.  
  575. ; Initialization routine.
  576. ;
  577. ; Call:         al/     yflags byte that was passed to Term routine
  578. ;               dl/     index for baud rate table
  579. ;               dh/     parity in bits 4-7, number of data bits in bits 0-3
  580. ;
  581.  
  582. ansini  proc    near
  583.         mov     yflags,al               ; Always save flags
  584.         mov     ah,vtemu.vtflgst        ; setup flags
  585.         mov     vtflags,ah
  586.         mov     vttabs,offset deftabs   ; tab stop pointer
  587.         mov     vtemu.vttbst,offset tabs; store here for STATUS
  588.         mov     al,flags.vtflg          ; get current terminal type
  589.         mov     oldterm,al              ; remember it here for soft restarts
  590.         mov     insmod,0                ; turn off insert mode
  591.         mov     h19l25,0                ; clear Heath 25th line enable
  592.         mov     h19ctyp,1               ; set Heath cursor to underline, on
  593.         mov     anspflg,0               ; clear printer flag
  594.         push    ax
  595.         mov     ah,byte ptr low_rgt     ; right most column (counted from 0)
  596.         sub     ah,8                    ; place marker 9 columns from margin
  597.         mov     belcol,ah               ; store column number to ring bell
  598.         pop     ax
  599.         cmp     dl,lbaudtab             ; Wierd index?
  600.         jb      ansin1                  ; No - OK - store it
  601.         mov     dl,lbaudtab-1           ; Yes - make it the maximum
  602. ansin1: mov     baudidx,dl              ; Save baud rate index
  603.         mov     al,dh                   ; Get parity/number of databits
  604.         and     al,0FH                  ; Isolate number of databits
  605.         mov     datbits,al              ; Save
  606.         mov     cl,4                    ; Isolate parity code
  607.         shr     dh,cl                   ; Isolate parity code
  608.         cmp     dh,lpartab              ; Weird code?
  609.         jb      ansin2                  ; No - OK - store it
  610.         mov     dh,lpartab-1            ; Yes - make it the maximum
  611. ansin2: mov     parcode,dh              ; Save
  612.         call    scrmod                  ; Get the screen mode, in MSYxxx
  613.         mov     cl,crt_cols             ; physical screen number columns (80)
  614.         dec     cl                      ; we count from column 0 here
  615.         mov     ch,crt_lins             ; physical screen number rows-1 (24)
  616.         dec     ch                      ; we count from row 0 here
  617.         mov     low_rgt,cx              ; save as active text screen size
  618.         mov     oldscrn,cx              ; remember old screen dimensions
  619. ansin3: call    atreset                 ; Reset everything
  620.         mov     ttstate,offset atnrm    ; Reset state to "normal"
  621.         ret                             ; And return
  622. ansini  endp
  623.  
  624.  
  625. ; Re-initialization routine. Called when Term was called but screen was
  626. ; restored from a previously saved screen, etc.
  627. ;
  628. ; Call: al/     yflags byte that was passed from msyibm module.
  629. ;
  630.  
  631. ansrei  proc    near
  632.         mov     yflags,al               ; Always save flags
  633.         mov     ah,vtemu.vtflgop        ; get runtime flags
  634.         mov     tmpflags,ah
  635.         call    scrmod                  ; Get the screen mode
  636.         call    atsctyp                 ; set cursor type [rbv]
  637.         mov     ah,3                    ; get cursor position from msy
  638.         mov     bh,0                    ; Page zero
  639.         int     screen                  ; physical = logical cursor here
  640.         mov     cursor,dx               ; dh = row, dl = column
  641.         mov     cl,crt_cols             ; physical screen number columns (80)
  642.         dec     cl                      ; we count from column 0 here
  643.         mov     ch,crt_lins             ; physical screen number rows-1 (24)
  644.         dec     ch                      ; we count from row 0 here
  645.         mov     low_rgt,cx              ; save as active text screen size
  646.         cmp     linelen,79              ; want 80 cols?
  647.         ja      ansre2                  ; a = no
  648.         cmp     byte ptr low_rgt,79     ; want 80 cols. Is active screen wider?
  649.         jbe     ansre2                  ; be = no
  650.         mov     byte ptr low_rgt,79     ; narrow down to 80 columns
  651. ansre2: test    vtemu.vtflgop,vswdir    ; writing right to left?
  652.         jz      ansre4                  ; z = no, left to right
  653.         sub     dl,byte ptr low_rgt     ; reflect cursor from right side
  654.         neg     dl
  655.         mov     cursor,dx               ; store as logical position
  656. ansre4: push    cx                      ; save current physical screen size
  657.         call    stblmds                 ; Check settable modes, set flags
  658.         pop     cx
  659.         cmp     cx,oldscrn              ; has screen size changed?
  660.         je      ansre3                  ; e = no, same as last time
  661.         mov     oldscrn,cx              ; remember new size
  662.         mov     mar_top,0               ; reset scrolling region
  663.         mov     al,byte ptr low_rgt+1
  664.         mov     mar_bot,al
  665.         jmp     atres2                  ; better do soft reset
  666. ansre3: ret
  667. ansrei  endp
  668.  
  669.  
  670. ; This routine copies the new tab stops when they have changed.
  671. ; Copies all 132 columns.
  672. cpytabs proc    near
  673.         mov     cx,swidth               ; number of screen columns
  674.         jcxz    cpytab1                 ; z = none to do
  675.         mov     si,vttabs               ; Source
  676.         mov     di,offset tabs          ; Destination
  677.         push    es                      ; save es
  678.         push    ds
  679.         pop     es                      ; set es to datas segment
  680.         cld
  681.         rep     movsb                   ; Do the copy
  682.         pop     es                      ; recover es
  683. cpytab1:ret
  684. cpytabs endp
  685.  
  686.  
  687. ; This routine checks to see whether any of the settable modes have changed
  688. ; (things that can be changed in both SETUP and by host commands), and
  689. ; changes those that need to be changed.  TMPFLAGS has the new VT100 setup
  690. ; flags, VTFLAGS has the old. This routine also updates VTFLAGS.
  691. ; Revised by [jrd] to allow MSY to reset scbattr when not in connect mode,
  692. ; to do "soft reset" if terminal type has changed, and to do a screen clear
  693. ; reset if the actual screen colors have changed.
  694.  
  695. stblmds proc    near
  696.         mov     al,flags.vtflg          ; get current terminal type
  697.         cmp     al,oldterm              ; same as before?
  698.         je      stblm10                 ; e = yes, skip over soft reset
  699.         mov     oldterm,al              ; remember current terminal type
  700.         mov     insmod,0                ; reset insert mode flag
  701.         mov     h19l25,0                ; reset heath-19 25th line enable
  702.         mov     mar_top,0               ; reset top scrolling margin
  703.         mov     al,byte ptr low_rgt+1   ; and scrolling margin
  704.         mov     mar_bot,al              ; to last normal line on screen
  705.         mov     ah,byte ptr low_rgt     ; right most column (counted from 0)
  706.         sub     ah,8                    ; place marker 9 columns from margin
  707.         mov     belcol,ah               ; store column number to ring bell
  708.         and     ansflgs,decckm+deckpam+decom+dececho ; save some flags
  709.         push    bx                      ; save this register around loop
  710.         mov     bx,offset linetype      ; setup to clear double width chars
  711.         mov     cx,slen                 ; number of linetype slots to clear
  712.         cmp     flags.vtflg,ttvt100     ; VT100 now?
  713.         jne     stblm0                  ; ne = no
  714.         or      ansflgs,decanm          ; set ansi flag bit
  715. stblm0: mov     byte ptr [bx],0         ; clear the linetype array to single
  716.         inc     bx                      ;  width characters
  717.         loop    stblm0                  ; do each line (1 byte per line)
  718.         pop     bx                      ; restore bx
  719. stblm10:mov     al,tmpflags             ; Get the new flags
  720.         and     ansflgs,not anslnm      ; assume we do not want newline
  721.         test    al,vsnewline            ; is newline mode desired?
  722.         jz      stblm1                  ; No - continue
  723.         or      ansflgs,anslnm          ; Yes - set corresponding mode flag
  724. stblm1: and     ansflgs,not decawm      ; assume not want wrap
  725.         test    al,vswrap               ; Did wrap mode change?
  726.         jz      stblm2                  ; No - continue
  727.         or      ansflgs,decawm          ; Yes - set corresponding mode flag
  728. stblm2:
  729. ;;      mov     ah,vtflags              ; old flags
  730. ;;      xor     ah,tmpflags             ; new flags
  731. ;;      test    ah,vsshift3             ; pick out char set bit
  732. ;;      jz      stblm4                  ; z = no change
  733. ;;      mov     ah,ascset               ; assume US ASCII
  734. ;;      test    tmpflags,vsshift3       ; Want UK?
  735. ;;      jz      stblm3                  ; No - guessed right
  736. ;;      mov     ah,ukset                ; Yes - use UK set
  737.         mov     ah,vtemu.vtchset        ; select char set from setup byte
  738. stblm3: mov     chr_sg0,ah              ; Set the sets
  739.         mov     chr_sg1,ah
  740. stblm4: mov     ah,oldbatr              ; get old screen background scbattr
  741.         mov     scbattr,ah              ; and update working copy
  742.         mov     ah,att_normal           ; get new attributes (Set Term Color)
  743.         push    bx
  744.         mov     bh,ah                   ; get new intensity bit of att_normal
  745.         and     bh,att_intensity
  746.         and     curattr,not att_intensity ; char attrs. clear intensity bit
  747.         or      curattr,bh              ; set new intensity
  748.         and     mlbattr,not att_intensity ; mode line attrs. clear intensity
  749.         and     scbattr,not att_intensity ; screen background attribute
  750.         or      scbattr,bh              ; set its intensity also
  751.         mov     bl,scbattr
  752.         mov     oldbatr,bl              ; and save it here as well
  753.         pop     bx
  754.         call    brkatt                  ; separate color and blink/bold
  755.         rol     ah,1                    ; reverse fore/back color fields
  756.         rol     ah,1
  757.         rol     ah,1
  758.         rol     ah,1
  759.         call    addatt                  ; put back blink/bold
  760.         push    bx                      ; check on color change
  761.         mov     bh,ah                   ; new att_reverse pattern
  762.         and     bh,not(att_intensity+att_blink) ; look at just color bits
  763.         mov     bl,att_reverse          ; previous att_reverse pattern
  764.         and     bl,not(att_intensity+att_blink) ; look at just color bits
  765.         mov     att_reverse,ah          ; save new reverse pattern
  766.         cmp     bh,bl                   ; have any color bits changed?
  767.         pop     bx                      ; does not affect flags
  768.         je      stblm9                  ; e = no
  769.         mov     cursor,0                ; reset cursor position
  770.         jmp     atres2                  ; go to semi-reset
  771. stblm9:                                 ; check on screen normal/reversed
  772.         mov     al,tmpflags
  773.         xor     al,vtflags              ; Find which ones have changed
  774.         test    al,vsscreen             ; How about screen background?
  775.         jz      stblm8                  ; No - don't touch it
  776.         test    tmpflags,vsscreen       ; Flag to be set?
  777.         jnz     stblm5                  ; Yes - go to it
  778.         and     ansflgs,not decscnm     ; No - cleared (normal video)
  779.         and     savflgs,not decscnm
  780.         mov     al,att_normal           ; No - get new background
  781.         jmp     short stblm6            ; And reverse everything
  782.  
  783. stblm5: or      ansflgs,decscnm         ; Set (reverse video)
  784.         or      savflgs,decscnm
  785.         mov     al,att_reverse          ; No - set reverse video
  786. stblm6: call    atrss2                  ; Reverse screen and cursor attribute
  787. stblm7: mov     al,scbattr              ; Reset saved attribute also
  788.         mov     savecu+svattr_index,al
  789.         mov     oldbatr,al              ; and save our attribute
  790. stblm8: mov     al,tmpflags             ; Get new flags
  791.         mov     vtflags,al              ; Store them
  792.         mov     ah,2                    ; set cursor
  793.         mov     bh,0                    ; page 0
  794.         mov     dx,cursor
  795.         call    direction               ; set cursor for writing direction
  796.         ret
  797. stblmds endp
  798.  
  799. ; Return screen offset - given rol, col in dx, returns offset of the word
  800. ; for that character from the screen origin in ax. Preserves all other regs.
  801. ; Use same routine in msy to more closely track screen width.
  802. ;;scrloc        proc    near
  803. ;;      push    bx                      ; We will use bx
  804. ;;      mov     al,dh                   ; Get row
  805. ;;      mov     bl,swidth               ; And length of a line
  806. ;;      mul     bl                      ; Offset for this row
  807. ;;      mov     dh,0                    ; Clear row
  808. ;;      add     ax,dx                   ; Word offset for this position
  809. ;;      sal     ax,1                    ; Make it a byte offset
  810. ;;      pop     bx                      ; Restore bx
  811. ;;      ret                             ; And return
  812. ;;scrloc        endp
  813.  
  814.  
  815.  
  816. ; Fetch status/attributes routine.
  817. ;
  818. ; Call:         al/     "yflags" byte from MSYxxx.
  819. ;
  820. ; Return:       ah/     mode line background attribute
  821. ;               al/     screen background attribute
  822. ;               bl/     current cursor attribute
  823. ;               bh/     ANSI (VT100) mode flags
  824.  
  825. anstat  proc    near
  826.         mov     yflags,al               ; Mostly for disleds
  827.         mov     ah,mlbattr              ; Return them our attrs, flags, etc
  828.         mov     al,scbattr
  829.         mov     bl,curattr
  830.         mov     bh,ansflgs
  831.         ret
  832. anstat  endp
  833.  
  834.  
  835. ; Routine called when something is typed on the keyboard
  836. ;
  837. ; Call:         No arguments
  838. ;
  839.  
  840. anskbi  proc    near
  841.         mov     ttkbi,0FFH              ; Just set a flag
  842.         ret
  843. anskbi  endp
  844.  
  845. ; Routine to do keyclick if flag is set.
  846. ;
  847. ; Call:         No arguments
  848. ;
  849.  
  850. vclick  proc    near
  851.         test    vtflags,vskeyclick      ; Is the flag on?
  852.         jz      vclick1                 ; No - just return
  853.         push    bx                      ; Save some ACs
  854.         push    di
  855.         mov     di,500                  ; 500 Hertz
  856.         mov     bx,1                    ; For 1 millisecond
  857.         call    vtsound                 ; Do it
  858.         pop     di                      ; Restore the ACs
  859.         pop     bx
  860. vclick1:ret
  861. vclick  endp
  862.  
  863.  
  864. ; Routine to do VT100-style bell.
  865. ;
  866. ; Call:         No arguments
  867. ;
  868.  
  869. vtbell  proc    near
  870.         push    di
  871.         push    bx
  872.         mov     di,880                  ; 880 Hertz
  873.         mov     bx,40                   ; For 40 ms
  874.         call    vtsound                 ; Do it
  875.         pop     bx
  876.         pop     di
  877.         ret
  878. vtbell  endp
  879.  
  880. ; Routine to make noise of arbitrary frequency for arbitrary duration.
  881. ; Similar to routine (with typo removed) in "IBM PC Assembly Language:
  882. ; A Guide for Programmers", Leo J. Scanlon, 1983 Robert J. Brady Co.,
  883. ; Bowie, MD., page 270. Modified by J R Doupnik to use 0.1 millsec interval.
  884. ;
  885. ; Call:         di/     frequency in Hertz.
  886. ;               bx/     duration in 1 millisecond units
  887. ;
  888.  
  889. vtsound proc    near
  890.         push    ax                      ; Save regs
  891.         push    cx
  892.         push    dx
  893.         mov     al,0B6H                 ; Write timer mode register
  894.         out     43H,al
  895.         mov     dx,14H                  ; Timer divisor is
  896.         mov     ax,4F38H                ; 1331000/frequency
  897.         div     di
  898.         out     42H,al                  ; Write timer 2 count low byte
  899.         mov     al,ah
  900.         out     42H,al                  ; Write timer 2 count high byte
  901.         in      al,61H                  ; Get current port B setting
  902.         or      al,3                    ; Turn speaker on
  903.         out     61H,al
  904.         mov     ax,bx                   ; number of milliseconds to wait
  905.         call    pcwait                  ; do the calibrated wait
  906.         in      al,61H                  ; Get current port B setting
  907.         and     al,0fch                 ; Turn off speaker and timer
  908.         out     61H,al
  909.         pop     dx                      ; Restore regs
  910.         pop     cx
  911.         pop     ax
  912.         ret
  913. vtsound endp
  914.  
  915. ; Routine to toggle VT100/VT52/Heath-19 modes. No arguments.
  916. ; Use & update global byte flags.vtflg for terminal type and update local
  917. ; bit decanm. Note: shifting to Heath-19 here does Not reset the scrolling
  918. ; margins mar_top & mar_bot nor reset the double char linetype array.
  919. ; [jrd]
  920. ans52t  proc    near
  921.         cmp     tekflg,0                ; in Tek sub mode?
  922.         jne     ans52c                  ; ne = yes, get out now
  923.         cmp     flags.vtflg,ttvt100     ; in VT100 mode?
  924.         jne     ans52a                  ; ne = no
  925.         and     ansflgs,not decanm      ; reset VT100 ansi mode
  926.         mov     flags.vtflg,ttvt52      ; say VT52 now (clears vt100 bit)
  927.         mov     oldterm,ttvt52          ; and remember it
  928.         jmp     ans52e
  929. ans52a: cmp     flags.vtflg,ttvt52      ; in VT52 mode?
  930.         jne     ans52b                  ; ne = no
  931.         mov     flags.vtflg,ttheath     ; say Heath-19 now
  932.         mov     oldterm,ttheath
  933.         jmp     ans52e
  934. ans52b: cmp     flags.vtflg,ttheath     ; in Heath-19 mode?
  935.         jne     ans52c                  ; ne = no
  936.         test    denyflg,tekxflg         ; is Tek mode disabled?
  937.         jz      ans52f                  ; z = no, enabled
  938.         mov     flags.vtflg,ttvt100     ; say VT100 now
  939.         mov     oldterm,ttvt100
  940.         or      ansflgs,decanm          ; set, go to VT100 mode
  941.         jmp     short ans52e
  942. ans52f: call    atsc                    ; save cursor and associated data
  943.         mov     flags.vtflg,tttek       ; set Tek mode
  944.         call    tekini                  ; init Tek to switch screens
  945.         jmp     atnorm                  ; normal state and return
  946. ans52c: cmp     flags.vtflg,tttek       ; in Tek mode now?
  947.         je      ans52d                  ; e = yes
  948.         cmp     tekflg,0                ; doing Tek sub mode?
  949.         jne     ans52d                  ; ne = yes
  950.         jmp     atnorm                  ; else ignore this call
  951.  
  952. ans52d: call    tekend                  ; exit Tek graphics mode
  953.         mov     tekflg,0                ; end Tek sub mode (do after tekend)
  954.         mov     flags.vtflg,ttvt100     ; say VT100 now
  955.         mov     oldterm,ttvt100
  956.         or      ansflgs,decanm          ; set, go to VT100 mode
  957.         call    atrc                    ; restore cursor etc
  958.         cmp     flags.modflg,0          ; is mode line disabled?
  959.         je      ans52e                  ; e = yes, disabled
  960.         test    yflags,modoff           ; Mode line off?
  961.         jnz     ans52e                  ; nz = yes - just return
  962.         mov     al,yflags               ; get current flags
  963.         or      al,modoff               ; say mode line is off
  964.         call    telmsy                  ; let msy hear the news
  965.         call    trnmod                  ; turn it on
  966. ans52e: call    chrdef                  ; Set default character sets
  967.         call    atsc                    ; Save cursor etc
  968.         call    disleds                 ; Remove or redisplay "LEDs"
  969.         jmp     atnorm                  ; Say state is "normal" and return
  970. ans52t  endp
  971.  
  972.  
  973. ; Display "LEDs" routine. Note that this routine
  974. ; is not used internally in this module (because it updates the flags from
  975. ; MSYIBM). Internally, disleds is used instead. The yflags from MSYIBM are
  976. ; needed because we have to know if the mode line is enabled.
  977. ;
  978. ; Call:         al/     yflags from MSYIBM
  979. ;
  980. ; Return:       Current state of "LEDs" displayed on line 25.
  981. ;
  982.  
  983. ansdsl  proc    near                    ; Update flags and display "LEDs"
  984.         mov     yflags,al               ; Update the flags
  985.         call    disleds                 ; Display LEDs
  986.         ret
  987. ansdsl  endp
  988.  
  989. ; Internal routine to display LEDs.
  990.  
  991. disleds:test    yflags,modoff           ; Mode line off?
  992.         jnz     disled2                 ; Yes - just return
  993.         cmp     flags.modflg,1          ; mode line on and owned by us?
  994.         ja      disled2                 ; a = no, leave it intact
  995.         mov     ah,2                    ; Position cursor at (slen-1),70
  996.         mov     bh,0                    ; Page zero
  997.         mov     dh,byte ptr low_rgt+1   ; last screen line - 1
  998.         inc     dh                      ; status line
  999.         mov     dl,led_col              ; column for led display
  1000.         int     screen
  1001.         mov     cx,10                   ; Length of byte array is ten
  1002.         mov     si,offset ansleds       ; The "LEDs"
  1003.         cmp     flags.vtflg,ttvt100     ; VT100 mode?
  1004.         je      disled1                 ; e = yes
  1005.         mov     si,offset v52leds       ; try VT52
  1006.         cmp     flags.vtflg,ttvt52      ; VT52?
  1007.         je      disled1                 ; e = yes
  1008.         mov     si,offset h19leds       ; use Heath-19
  1009. disled1:lodsb                           ; Get a character
  1010.         mov     ah,14                   ; Write character function
  1011.         mov     bh,0                    ; Page zero
  1012.         int     screen
  1013.         loop    disled1                 ; Loop for all chars
  1014.         mov     ah,2                    ; Reposition cursor when finished
  1015.         mov     bh,0                    ; Page zero
  1016.         mov     dx,cursor
  1017.         call    direction               ; do Bios screen operation
  1018.         call    atsctyp                 ; Reset right type of cursor
  1019. disled2:ret
  1020.  
  1021.  
  1022. ; ANSI terminal output routine.  Call with character in al.
  1023.  
  1024. anstty  proc    near                    ; ANSI terminal output
  1025.         mov     dx,cursor               ; Some routines need cursor in dx
  1026.         mov     kbiflg,0                ; Clear old flag value
  1027.         test    yflags,trnctl           ; Debug mode?
  1028.         jz      anstt1                  ; z = no
  1029.         jmp     atdeb                   ; Yes - just translate control chars
  1030. anstt1: cmp     ttkbi,0                 ; New keyboard input?
  1031.         je      anstt2                  ; No - just continue
  1032.         mov     kbiflg,1                ; Yes - set flag
  1033.         mov     kbicsr,dx               ; Save old cursor
  1034.         mov     ttkbi,0                 ; Clear this flag
  1035.  
  1036. anstt2: test    anspflg,vtcntp          ; print controller on?
  1037.         jz      anstt4                  ; z = no
  1038.         test    yflags,capt             ; capturing output?
  1039.         jz      anstt3                  ; z = no, forget this part
  1040.         push    ax                      ; save char
  1041.         call    cptchr                  ; give it captured character
  1042.         pop     ax                      ; restore character
  1043. anstt3: jmp     ansmc                   ; print transparently
  1044.                                         ; Set Display 7/8 bit filter
  1045. anstt4: test    flags.remflg,d8bit      ; keep 8 bits for displays?
  1046.         jnz     anstt5                  ; nz = yes, 8 bits if possible
  1047.         and     al,7fh                  ; remove high bit
  1048. anstt5: cmp     al,spc                  ; control char?
  1049.         jb      anstt6                  ; b = yes
  1050.         cmp     ttstate,offset atnrm    ; doing displayable text?
  1051.         jne     anstt7                  ; ne = no, no translation
  1052.                                         ; Set Translation filter
  1053. anstt6: cmp     rxtable+256,0           ; translation turned off?
  1054.         je      anstt7                  ; e = yes, no translation
  1055.         mov     bx,offset rxtable       ; address of translate table
  1056.         xlatb                           ; new char is in al
  1057. anstt7: cmp     al,DEL                  ; ANSI Delete char?
  1058.         je      atdel                   ; e = yes, ignore it before logging
  1059.         cmp     al,0                    ; NUL char?
  1060.         je      atign                   ; e = yes, ignore it before logging
  1061.         test    yflags,capt             ; capturing output?
  1062.         jz      anstt8                  ; z = no, forget this part
  1063.         push    ax                      ; save char
  1064.         call    cptchr                  ; give it captured character
  1065.         pop     ax                      ; restore character and keep going
  1066.                                         ; Direct char to processor module
  1067. anstt8: cmp     al,20h                  ; Control character?
  1068.         jb      atctrl                  ; b = yes, handle it
  1069. anstt9: jmp     ttstate                 ; Nope, dispatch according to state
  1070.  
  1071. atign:  ret                             ; Something to be ignored
  1072.  
  1073. atctrl: mov     ah,0                    ; Make sure this is zero.
  1074.         cmp     al,escape               ; an escape sequence starting?
  1075.         je      atctrl1                 ; e = yes, don't print it
  1076.         test    anspflg,vtautop+vtcntp  ; printing desired?
  1077.         jz      atctrl1                 ; z = no
  1078.         call    pntchr                  ; print char in al
  1079. atctrl1:mov     di,ax                   ; Put it in an index register
  1080.         shl     di,1                    ; Make it a word offset
  1081.         jmp     ansspc[di]              ; Dispatch
  1082.  
  1083. atdel:  jmp     short atign             ; ignore DEL char
  1084.  
  1085. atdeb:  test    yflags,capt             ; capturing output?
  1086.         jz      atdeb3                  ; z = no, forget this part
  1087.         push    ax                      ; save char
  1088.         call    cptchr                  ; give it captured character
  1089.         pop     ax                      ; restore character and keep going
  1090. atdeb3: mov     bh,ansflgs              ; Save flags and attribute
  1091.         mov     bl,curattr
  1092.         push    bx
  1093.         push    word ptr mar_top        ; Save limited scrolling region
  1094.         push    ax                      ; Save character for a second
  1095.         mov     ah,curattr              ; Get attribute
  1096.         call    brkatt                  ; Break it up
  1097.         and     al,att_intensity        ; clear attributes, except bold bit
  1098.         call    addatt                  ; Put it back together
  1099.         mov     curattr,ah              ; Store
  1100.         or      ansflgs,decawm          ; Set autowrap temporarily
  1101.         mov     mar_top,0               ; Set scrolling region to entire page
  1102.         mov     al,byte ptr low_rgt+1
  1103.         mov     mar_bot,al
  1104.         pop     ax                      ; Restore character
  1105.         test    al,80h                  ; high bit set?
  1106.         jz      atdeb0                  ; z = not set
  1107.         push    ax                      ; Save the character for a second
  1108.         mov     al,7eh                  ; Output a tilde
  1109.         call    atnrm2
  1110.         pop     ax                      ; Restore character
  1111.         and     al,7fh                  ; and remove high bit
  1112. atdeb0: cmp     al,del                  ; A DELETE?
  1113.         je      atdeb1                  ; Yes - output "~?"
  1114.         cmp     al,20h                  ; A control character?
  1115.         jnb     atdeb2                  ; No - just output char in al
  1116. atdeb1: push    ax                      ; Save the character for a second
  1117.         mov     al,5eh                  ; Output a caret
  1118.         call    atnrm2
  1119.         pop     ax                      ; Restore character
  1120.         add     al,40h                  ; Make ~letter (or ~? for DELETE)
  1121.         and     al,7fh                  ; Clear bit 7 (for DELETE)
  1122. atdeb2: call    atnrm2                  ; Output translated character
  1123.         pop     word ptr mar_top        ; Restore scrolling region
  1124.         pop     bx                      ; And flags and cursor attribute
  1125.         mov     curattr,bl
  1126.         mov     ansflgs,bh
  1127.         ret
  1128.  
  1129. atnorm: mov     ttstate,offset atnrm    ; Reset state to "normal".
  1130.         ret
  1131.  
  1132.                                         ; Normal character processor
  1133. atnrm:  mov     bx,chr_set              ; Get character set
  1134.         cmp     byte ptr [bx],ascset    ; standard US ascii?
  1135.         je      atnrm2                  ; e = yes
  1136.         cmp     byte ptr [bx],alcset    ; Alternate character set? [bk]
  1137.         jne     atnrm0b                 ; ne = no [bk]
  1138.         cmp     al,('a'-1)              ; replace a..z with 128d - (a..z) [bk]
  1139.         jb      atnrm2                  ; b = out of range
  1140.         cmp     al,'z'
  1141.         ja      atnrm2                  ; a = out of range
  1142.         add     al,(80h-('a'-1))        ; map up by 20h
  1143.         jmp     short atnrm2
  1144.  
  1145. atnrm0b:cmp     byte ptr [bx],sgrset    ; "Special" set?
  1146.         jne     atnrm1                  ; No - check UK
  1147.         cmp     flags.vtflg,ttheath     ; Heath-19?
  1148.         je      atnrm0a                 ; e = yes
  1149.         cmp     al,137Q                 ; Yes - is it in the "special" range?
  1150.         jb      atnrm2                  ; No - just output the char in al
  1151.         mov     bl,al                   ; Yes - compute index in bx
  1152.         mov     bh,0
  1153.         sub     bx,137Q
  1154.         mov     al,sgrtab[bx]           ; Fetch translation
  1155.         jmp     short atnrm2            ; Output it
  1156.  
  1157. atnrm0a:cmp     al,94                   ; H-19, in range for special graphics?
  1158.         jb      atnrm2                  ; b = no
  1159.         cmp     al,126                  ; too large?
  1160.         ja      atnrm2                  ; a = too large
  1161.         sub     bx,94                   ; H-19, offset from caret
  1162.         mov     bl,al
  1163.         mov     bh,0
  1164.         sub     bx,94
  1165.         mov     al,hgrtab[bx]           ; fetch translation
  1166.         jmp     short atnrm2
  1167.  
  1168. atnrm1: cmp     al,'#'                  ; This thing?
  1169.         jne     atnrm2                  ; No - just output it
  1170.         cmp     byte ptr [bx],ukset     ; Yes - UK set?
  1171.         jne     atnrm2                  ; No - just output it
  1172.         mov     al,156                  ; Yeah, show them our pound sign
  1173. atnrm2: cmp     al,9bh                  ; ANSI CSI char?
  1174.         jne     atnrm2b                 ; ne = no
  1175.         jmp     at9bh                   ; yes, process ANSI CSI as "ESC ["
  1176. atnrm2b:mov     dx,cursor               ; get cursor virtual position
  1177.         push    ax                      ; save character
  1178.         call    atscur                  ; set cursor physical position
  1179.         pop     ax
  1180.  
  1181.         cmp     insmod,0                ; insert mode off?
  1182.         je      atnrm3                  ; e = yes
  1183.         push    ax                      ; save char
  1184.         call    inschr                  ; open a char space in this line
  1185.         push    bx
  1186.         mov     bx,cursor               ; get current row
  1187.         mov     bl,bh
  1188.         mov     bh,0
  1189.         cmp     linetype [bx],0         ; single width line?
  1190.         je      atnrm2a                 ; e = yes
  1191.         call    inschr                  ; open second space for double width
  1192. atnrm2a:pop     bx
  1193.         pop     ax                      ; restore char
  1194. atnrm3:                                 ; set cursor before writing char
  1195.         mov     bl,dh                   ; check for double characteristic
  1196.         xor     bh,bh                   ; bx = row, in bl
  1197.  
  1198.         test    anspflg,vtautop         ; printing desired?
  1199.         jz      atnrm4d                 ; e = no
  1200.         call    pntchr                  ; print char in al
  1201.         cmp     linetype [bx],0         ; normal characteristic?
  1202.         je      atnrm4d                 ; e = yes
  1203.         push    ax                      ; save current char
  1204.         mov     al,' '                  ; add a space for double width
  1205.         call    pntchr
  1206.         pop     ax                      ; recover char to be processed
  1207. atnrm4d:
  1208.         cmp     linetype [bx],0         ; normal characteristic?
  1209.         je      atnrm4a                 ; e = yes
  1210.         push    ax                      ; save char
  1211.         shl     dl,1                    ; double the column number
  1212.         mov     ah,2                    ; set cursor (bh = 0 from above)
  1213.         call    direction               ; do Bios screen operation
  1214.         pop     ax                      ; recover the char
  1215.         mov     ah,9                    ; Output char in al to screen
  1216.         mov     bh,0                    ; Page zero
  1217.         mov     bl,curattr              ; Current attribute
  1218.         mov     cx,1                    ; Only one character
  1219.         int     screen
  1220.         inc     dl                      ; next column
  1221.         mov     ah,2                    ; set cursor
  1222.         call    direction               ; do Bios screen operation
  1223.         mov     al,' '                  ; use a space for doubling
  1224.         mov     ah,9                    ; Output to screen
  1225.         mov     bh,0                    ; Page zero
  1226.         mov     bl,curattr              ; Current attribute
  1227.         mov     cx,1                    ; Only one character
  1228.         int     screen
  1229.         shr     dl,1                    ; keep "cursor" in single units
  1230.         jmp     atnrm4b                 ; check autowrap in double width mode
  1231.  
  1232. atnrm4a:mov     ah,9                    ; Output to screen
  1233.         mov     bh,0                    ; Page zero
  1234.         mov     bl,curattr              ; Current attribute
  1235.         mov     cx,1                    ; Only one character
  1236.         int     screen
  1237.                                         ; set physical cursor after this char
  1238. atnrm4b:test    ansflgs,decawm          ; Autowrap?
  1239.         jz      atnrm5                  ; No, continue
  1240.         mov     cx,low_rgt              ; copy logical cursor margins to cx
  1241.         push    bx
  1242.         mov     bl,dh                   ; get row
  1243.         xor     bh,bh
  1244.         cmp     linetype[bx],0          ; single width line?
  1245.         pop     bx                      ; pop preserves flags
  1246.         je      atnrm4c                 ; e = yes, single
  1247.         shr     cl,1                    ; halve right column # for wide chars
  1248. atnrm4c:cmp     dl,cl                   ; wrote in right-most column?
  1249.         jb      atnrm5                  ; b = no
  1250.         inc     dl                      ; say want to use next column
  1251.         cmp     flags.vtflg,ttheath     ; emulating a H-19? [uci]
  1252.         je      atscur                  ; e = yes, show wrap now. [uci]
  1253.         mov     cursor,dx               ; virtual cursor position
  1254.         ret                             ; exit without moving cursor from eol
  1255. atnrm5: mov     dx,cursor               ; Restore cursor position
  1256.         inc     dl                      ; Bump cursor
  1257.  
  1258. atscur: cmp     dl,250                  ; To left of column zero?(wide screen)
  1259.         jb      atscu1                  ; b = no, continue
  1260.         mov     dl,0                    ; Yes - set at column zero
  1261. atscu1: mov     cx,low_rgt              ; copy logical margins; cl=right col
  1262.         push    bx
  1263.         mov     bl,dh                   ; get row
  1264.         xor     bh,bh
  1265.         cmp     linetype [bx],0         ; single width lines?
  1266.         pop     bx
  1267.         je      atscu1a                 ; e = yes, single width
  1268.         shr     cl,1                    ; halve column # for double wides
  1269. atscu1a:cmp     dl,cl                   ; To right of right margin?
  1270.         jbe     atscu3                  ; be = no, continue
  1271.         mov     dl,cl                   ; Yes - assume no autowrap
  1272.         test    ansflgs,decawm          ; Autowrap?
  1273.         jz      atscu3                  ; No, continue
  1274.         mov     dl,0                    ; Yes - set to column zero
  1275.         cmp     dh,byte ptr low_rgt+1   ; at bottom of screen?
  1276.         je      atscu1b                 ; e = yes
  1277.         cmp     dh,mar_bot              ; At bottom of scrolling region?
  1278.         jl      atscu2                  ; l = No - bump cursor and continue
  1279. atscu1b:mov     scroll,1                ; scroll count = 1 line
  1280.         call    atscru                  ; Scroll up
  1281.         dec     dh                      ; offset inc dh below
  1282. atscu2: inc     dh                      ; Just bump it
  1283. atscu3: cmp     dh,0                    ; Constrain row to valid range
  1284.         jge     atscu4                  ; ge = non-negative row, ok
  1285.         mov     dh,0
  1286. atscu4: cmp     dh,byte ptr low_rgt+1   ; 25th line?
  1287.         jle     atscu5                  ; le = no
  1288.         mov     dh,byte ptr low_rgt+1   ; set to 24th line
  1289.         cmp     flags.vtflg,ttheath     ; emulating a Heath-19?
  1290.         jne     atscu4a                 ; ne = no [hlk]
  1291.         cmp     h19l25,0                ; Heath 25th line enabled?
  1292.         je      atscu5                  ; e = no
  1293. atscu4a:inc     dh                      ; yes, go to line 25 [hlk]
  1294.         test    yflags,modoff           ; is mode line off?
  1295.         jnz     atscu8                  ; nz = yes
  1296.         push    dx                      ; save cursor position
  1297.         call    trnmod                  ; no, turn it off now
  1298.         and     yflags,not modoff       ; now say it's on (owned by host)
  1299.         pop     dx
  1300. atscu8: mov     flags.modflg,2          ; say mode line is owned by host
  1301.         mov     al,yflags               ; place to communicate
  1302.         call    telmsy                  ; tell msy the news
  1303.  
  1304. atscu5: push    cx                      ; save cx around screen call
  1305.         mov     cursor,dx               ; Set cursor and return
  1306.         mov     ah,2                    ; setup for position cursor call
  1307.         mov     bl,dh                   ; get row
  1308.         mov     bh,0
  1309.         cmp     linetype [bx],0         ; single width line?
  1310.         je      atscu5a                 ; e = yes
  1311.         shl     dl,1                    ; double the column number
  1312.         call    direction               ; do Bios screen operation
  1313.         shr     dl,1                    ; restore dl (logical column)
  1314.         jmp     short atscu5b
  1315. atscu5a:call    direction               ; do Bios screen operation
  1316. atscu5b:pop     cx
  1317.         cmp     kbiflg,0                ; Is keyboard input flag set?
  1318.         je      atscu6                  ; No - just return
  1319.         test    vtflags,vsmarginbell    ; Yes - do we care?
  1320.         jz      atscu6                  ; Return if no margin bell
  1321.         mov     dx,cursor               ; Get new and old cursors
  1322.         mov     bx,kbicsr
  1323.         cmp     bh,dh                   ; Same row?
  1324.         jne     atscu6                  ; No - just return
  1325.         cmp     bl,belcol               ; Old cursor at or left of bell column?
  1326.         ja      atscu6                  ; a = no, just return
  1327.         cmp     dl,belcol               ; Yes - new cursor past bell column?
  1328.         jbe     atscu6                  ; be = no, just return
  1329.         call    vtbell                  ; Yes - ring the bell
  1330. atscu6: ret
  1331.  
  1332. ; This routine is called to check the cursor position after any kind of cursor
  1333. ; positioning command.  Note that cursor positioning does NOT cause scrolling
  1334. ; on a VT100 (hence the need for a routine separate from this for "indexing".
  1335. ;
  1336. ; Call:         dx/     "new" cursor position (modified cursor)
  1337. ;
  1338. ; Return:       dx/     "new" cursor position adjusted for screen limits (if
  1339. ;                       decom is reset), or scrolling region (if decom is set).
  1340. ;
  1341. ; Preserves ax, bx, and cx.
  1342. ;
  1343.  
  1344. atccpc: push    bx                      ; save bx and cx
  1345.         push    cx
  1346. atccp7: mov     cx,low_rgt              ; margins, cl = right margin
  1347.         mov     bl,dh                   ; get row
  1348.         xor     bh,bh
  1349.         cmp     linetype [bx],0         ; single width line?
  1350.         je      atccp0                  ; e = yes, single width
  1351.         shr     cl,1                    ; halve right margin for double wides
  1352. atccp0: cmp     dl,250                  ; To left of left margin?(wide screen)
  1353.         jb      atccp1                  ; b = no, go check right
  1354.         mov     dl,0                    ; No, set to left margin
  1355. atccp1: cmp     dl,cl                   ; To right of right margin
  1356.         jbe     atccp2                  ; be = yes, go check top
  1357.         mov     dl,cl                   ; No, set to right margin
  1358. atccp2: test    ansflgs,decom           ; Origin mode set?
  1359.         jnz     atccp5                  ; Yes, can't go out of scrolling region
  1360.         cmp     dh,0                    ; Above top of screen?
  1361.         jge     atccp3                  ; ge = no, check bottom
  1362.         mov     dh,0                    ; Yes, stop here
  1363. atccp3: cmp     dh,byte ptr low_rgt+1   ; Below bottom of screen?
  1364.         jle     atccp4                  ; le = no, return
  1365.         mov     dh,byte ptr low_rgt+1   ; Yes, stop at bottom margin
  1366.         cmp     flags.vtflg,ttheath     ; Heath-19 mode?
  1367.         jne     atccp4                  ; ne = no
  1368.         cmp     h19l25,0                ; 25th line enabled?
  1369.         je      atccp4                  ; e = no
  1370.         inc     dh                      ; allow 25th line
  1371. atccp4: pop     cx
  1372.         pop     bx
  1373.         ret
  1374.  
  1375. atccp5: cmp     dh,mar_top              ; Above top of scrolling region?
  1376.         jge     atccp6                  ; ge = no, check bottom
  1377.         mov     dh,mar_top              ; Yes, stop there
  1378. atccp6: cmp     dh,mar_bot              ; Below bottom perhaps?
  1379.         jle     atccp4                  ; le = no, return
  1380.         mov     dh,mar_bot              ; Yes, stop at the bottom margin
  1381.         pop     cx
  1382.         pop     bx
  1383.         ret
  1384.  
  1385.  
  1386. ; This routine is called to adjust the cursor for the "indexing" like commands
  1387. ; (e.g., index, reverse index, newline, etc.).  It contrains the cursor, and
  1388. ; indicates if scrolling is necessary, and if so, in which direction.
  1389. ;
  1390. ; Call:         cursor/ "old" cursor position
  1391. ;               dx/     "new" cursor position
  1392. ;
  1393. ; Return:       ax/     pointer to scrolling routine to call (or to a ret)
  1394. ;               bx/     "old" cursor position
  1395. ;               dx/     "new" cursor position adjusted for screen limits or
  1396. ;                       scrolling region, depending on whether the original
  1397. ;                       cursor position was inside or outside the scrolling
  1398. ;                       region.
  1399. ;
  1400. ; On the VT100, a scroll does not occur unless the original cursor position
  1401. ; was on the top or bottom margin.    This routine assumes that when decom is
  1402. ; set the cursor position is set to the new origin, and that no other routine
  1403. ; allows the cursor to be positioned outside the scrolling region as long
  1404. ; as decom is set (which is the way a real VT100 works).  Note that for the
  1405. ; normal case (no limited scrolling region defined) the margins are the same
  1406. ; as the screen limits and scrolling occurs (as on a "normal" terminal) when
  1407. ; an attempt is made to index off the screen. Preserves cx.
  1408. ; Revised 16 June 1987 [jrd]
  1409.  
  1410. atccic: push    cx
  1411.         mov     cx,low_rgt              ; get margins, cl = right margin
  1412.         mov     bl,dh                   ; get row
  1413.         xor     bh,bh
  1414.         cmp     bl,ch                   ; Below screen?
  1415.         ja      atcci0                  ; a = yes, use single width line
  1416.         cmp     linetype[bx],0          ; single width chars?
  1417.         je      atcci0                  ; e = yes, single width
  1418.         shr     cl,1                    ; halve margin for double wides
  1419. atcci0: mov     ax,offset atign         ; Assume no scrolling necessary
  1420.         mov     bx,cursor               ; Get old cursor
  1421.         cmp     dl,250                  ; To left of left margin?(wide screen)
  1422.         jb      atcci1                  ; b = no, go check right
  1423.         mov     dl,0                    ; No, set to left margin
  1424. atcci1: cmp     dl,cl                   ; To right of right margin
  1425.         jbe     atcci2                  ; be = yes, go check top
  1426.         mov     dl,cl                   ; No, set to right margin
  1427. atcci2: cmp     bh,mar_top              ; was old pos at scrolling top margin?
  1428.         jne     atcci5                  ; ne = no, check other end
  1429.         cmp     dh,mar_top              ; want to go above top margin?
  1430.         jge     atcci7                  ; ge = no
  1431.         mov     scroll,1
  1432.         mov     ax,offset atscrd        ; Yes, indicate scroll down required
  1433.         mov     dh,mar_top              ; Set to top margin
  1434.         jmp     atcci7
  1435.  
  1436. atcci5: cmp     bh,mar_bot              ; Was old position at bottom margin?
  1437.         jne     atcci7                  ; ne = no, so don't trap cursor
  1438.         cmp     dh,mar_bot              ; want to go below?
  1439.         jb      atcci7                  ; b = no, nothing to worry about
  1440.         mov     scroll,1                ; 1 line
  1441.         mov     ax,offset atscru        ; Yes, indicate scroll up required
  1442. atcci6: mov     dh,mar_bot              ; Set to bottom margin
  1443.         pop     cx
  1444.         ret
  1445. atcci7: pop     cx                      ; old pos was outside scrolling region
  1446.         jmp     atccpc                  ; do full screen check and return
  1447.  
  1448. ; This routine picks an attribute apart into its component "parts" - the
  1449. ; base attribute for the screen and the "extras" - i.e., blink, intensity
  1450. ; and underline.
  1451. ;
  1452. ; Call:         ah/     a cursor attribute
  1453. ;
  1454. ; Return:       ah/     base attribute for screen (07H normal, 70H reverse).
  1455. ;               al/     "extra" attributes
  1456. ;
  1457. ; Note that there is a complementary routine, addatt, for putting attributes
  1458. ; back together.
  1459. ;
  1460.  
  1461. brkatt: mov     al,0                    ; Clear returned "extra" attributes
  1462.         cmp     crt_mode,7              ; monochrome display adapter mode?
  1463.         jne     brkat2                  ; ne = no. cut this short for color
  1464.         test    ah,att_low_mask         ; Any of these on?
  1465.         jnz     brkat1                  ; Yes, can't be underline
  1466.         test    ah,att_underline        ; Underline?
  1467.         jz      brkat2                  ; No, some kind of reverse video
  1468.         or      al,att_underline        ; Yes, say underline
  1469.         test    ah,70h ;;att_reverse    ; Reverse video + underline?
  1470.         jz      brkat1                  ; No, fix up low nibble
  1471.         and     ah,not att_underline    ; Yes, clear the underline bit in ah
  1472.         jmp short brkat2                ; And forge on
  1473.  
  1474. brkat1: or      ah,att_normal           ; Normal - turn on all normal bits
  1475. brkat2: test    ah,att_intensity        ; Intensity attribute on?
  1476.         jz      brkat3                  ; No - check blink
  1477.         or      al,att_intensity        ; Yes - turn on the bit
  1478. brkat3: test    ah,att_blink            ; Blink on?
  1479.         jz      brkat4                  ; No - forge on
  1480.         or      al,att_blink            ; Yes - turn on the bit
  1481. brkat4: and     ah,not(att_intensity+att_blink) ;strip blink/bold, leave color
  1482.         ret
  1483.  
  1484. ; This routine builds a cursor attribute given the base attribute for the
  1485. ; screen background and the "extra" attributes we want (blink, etc.).
  1486. ;
  1487. ; Call:         ah/     base attribute for background (07H or 70H)
  1488. ;               al/     "extra" attributes (89H for all three)
  1489. ;
  1490. ; Return:       ah/     base combined with "extras".
  1491. ;
  1492.  
  1493. addatt: test    al,att_underline        ; Want underline?
  1494.         jz      addat1                  ; No - no need for hack
  1495.         and     ah,not att_low_mask     ; Yes - clear these bits
  1496. addat1: or      ah,al                   ; Or in the attributes
  1497.         ret
  1498.  
  1499.  
  1500. ; This routine is called when we want to reverse everything on the screen
  1501. ; from normal to reverse video, or vice versa.  It is called only when
  1502. ; the decscnm attribute is changed.
  1503. ;
  1504. ; Call:         no arguments.
  1505. ;
  1506. ; This routine may destroy ax-dx
  1507. ;
  1508.  
  1509. revscn: mov     dh,byte ptr low_rgt+1   ; Compute last screen offset in ax
  1510.         inc     dh                      ; One more row to catch mode line
  1511.         mov     dl,crt_cols             ; physical width
  1512.         dec     dl                      ; and we count from 0
  1513.         call    scrloc
  1514.         mov     cx,ax                   ; Save it in cx for a minute
  1515.         mov     dx,0                    ; Compute first screen offset in ax
  1516.         call    scrloc
  1517.         sub     cx,ax                   ; Compute number of locs to change.
  1518.         add     cx,2
  1519.         sar     cx,1                    ; In 16-bit words please
  1520.         push    di                      ; Save some more acs
  1521.         push    es
  1522.         push    cx                      ; save word count for Topview
  1523.         push    ax                      ; save screen displacement
  1524.         call    scrseg                  ; Get address of screen in ax, es:di
  1525.         pop     ax                      ; recover displacement
  1526.         add     di,ax                   ; displacement addr of start of change
  1527.         call    scroff                  ; Turn screen off if color card
  1528. revsc1: mov     ax,es:[di]              ; Fetch a word
  1529.         mov     bl,al                   ; Save the character
  1530.         call    brkatt                  ; Break up the attributes
  1531.         rol     ah,1                    ; Reverse the video
  1532.         rol     ah,1                    ; Reverse the video
  1533.         rol     ah,1                    ; Reverse the video
  1534.         rol     ah,1                    ; Reverse the video
  1535.         call    addatt                  ; Put attributes back together
  1536.         mov     al,bl                   ; Restore character
  1537.         mov     es:[di],ax              ; Stuff into screen memory
  1538.         add     di,2                    ; Point di to next word of screen mem
  1539.         loop    revsc1                  ; Loop for entire screen
  1540.         pop     cx                      ; recover word count for Topview
  1541.         call    scrsync                 ; synch with Topview
  1542.         call    scron                   ; Turn screen back on if color card
  1543.         pop     es                      ; Restore segment register
  1544.         pop     di                      ; And destination index
  1545.         ret
  1546.  
  1547.  
  1548. ; Reset-everything routine.
  1549.  
  1550. atreset:mov     al,0                    ; Make cursor disappear for a while
  1551. ;;      call    csrtype
  1552.         mov     cursor,0                ; Cursor is at 0,0
  1553.         mov     ansflgs,0               ; reset these flags
  1554.         mov     escdec,0
  1555.         cmp     flags.vtflg,ttvt100     ; VT100?
  1556.         jne     atres7                  ; ne = no
  1557.         mov     ansflgs,decanm          ; turn on ANSI mode flag
  1558. atres7: mov     mar_top,0               ; Reset scrolling region
  1559.         mov     al,byte ptr low_rgt+1
  1560.         mov     mar_bot,al
  1561.         mov     ah,vtemu.vtflgst
  1562.         mov     vtemu.vtflgop,ah
  1563.         mov     vtflags,ah
  1564.         mov     insmod,0                ; reset insert mode
  1565.         mov     h19l25,0                ; clear heath 25th line enable
  1566.         mov     h19ctyp,1               ; Heath-19 cursor to underline
  1567.         mov     anspflg,0               ; clear printer flag
  1568.         mov     cx,4                    ; Initialize the "LEDs"
  1569.         mov     al,led_off              ; Turn them all off
  1570.         mov     di,offset ansleds+6     ; Point to the "LEDs"
  1571.         push    es                      ; save es
  1572.         push    ds
  1573.         pop     es                      ; use datas segment for es:di below
  1574.         cld                             ; set forward direction
  1575.         rep     stosb                   ; Do it
  1576.         pop     es
  1577.         call    disleds                 ; update mode line
  1578.         mov     vttabs,offset deftabs
  1579.         call    cpytabs                 ; Initialize tab stops
  1580.         call    chrdef                  ; Set default character set
  1581.         call    vtbell                  ; Ding bell like VT100
  1582.         test    vtflags,vsnewline       ; Want ANSI newline mode?
  1583.         jz      atres1                  ; No
  1584.         or      ansflgs,anslnm          ; Yes - set it in the mode flags
  1585. atres1: test    vtflags,vswrap          ; How about autowrap?
  1586.         jz      atres2                  ; No
  1587.         or      ansflgs,decawm          ; Yes - set it in the mode flags
  1588. atres2: mov     ah,att_normal           ; get present normal coloring
  1589.         call    brkatt                  ; separate color and blink/bold
  1590.         rol     ah,1                    ; reverse fore/back color fields
  1591.         rol     ah,1
  1592.         rol     ah,1
  1593.         rol     ah,1
  1594.         call    addatt                  ; put back blink/bold
  1595.         mov     att_reverse,ah          ; this is the reverse video code
  1596.         mov     al,att_normal           ; Assume normal video
  1597.         test    vtflags,vsscreen        ; Want reverse video?
  1598.         jz      atres3                  ; No
  1599.         or      ansflgs,decscnm         ; Yes - turn on the mode flag
  1600.         xchg    al,ah                   ; And reverse the video
  1601. atres3: mov     cx,slen                 ; typically 24 but do max lines
  1602.         mov     di,0
  1603. atres8: mov     linetype[di],0          ; clear the linetype array to single
  1604.         inc     di                      ; width/height characters
  1605.         loop    atres8
  1606.         mov     curattr,al              ; Give cursor and screen nice
  1607.         mov     scbattr,al              ; attributes.
  1608.         mov     oldbatr,al              ; place to remember long term
  1609.         mov     mlbattr,ah              ; Give the other to the mode line
  1610.         and     mlbattr,not att_intensity       ; turn off intensity bit
  1611.         mov     video_state,0           ; say normal video
  1612.         mov     ax,0                    ; Clear entire screen
  1613.         mov     bx,low_rgt
  1614.         mov     bl,crt_cols
  1615.         dec     bl                      ; do physical screen
  1616.         call    atsclr
  1617.         mov     dx,cursor               ; Set cursor to 0,0
  1618.         call    atscu5
  1619.         call    atsc                    ; Give saved cursor reasonable values
  1620.         call    atsctyp                 ; Set right cursor type
  1621.         mov     al,yflags
  1622.         call    telmsy                  ; update msy about ansflgs state
  1623.  
  1624.         test    yflags,modoff           ; is mode line off?
  1625.         jnz     atres9                  ; nz = yes
  1626.         push    dx                      ; save cursor position
  1627.         call    trnmod                  ; toggle off then on again so we
  1628.         call    trnmod                  ;   use it with current coloring
  1629.         pop     dx
  1630. atres9: ret
  1631.  
  1632. ; Routine to set cursor type (block, underline).
  1633.  
  1634. atsctyp:cmp     flags.vtflg,ttheath     ; Heath-19?
  1635.         jne     atsct0                  ; ne = no
  1636.         mov     al,h19ctyp              ; get cursor kind and on/off bit
  1637.         test    al,4                    ; is cursor to be off?
  1638.         jz      atsct1                  ; z = no, al has kind
  1639.         mov     al,0                    ; turn off cursor
  1640.         jmp     short atsct1            ; do it
  1641. atsct0: mov     al,1                    ; Assume underline
  1642.         test    vtemu.vtflgop,vscursor  ; Want block?
  1643.         jnz     atsct1                  ; nz = no, underline
  1644.         mov     al,2                    ; Yes
  1645. atsct1: call    csrtype                 ; Do it
  1646.         ret
  1647.  
  1648. ; Routine to set default character set.
  1649.  
  1650. chrdef: mov     al,vtemu.vtchset        ; get setup default character set
  1651. chrde1: mov     chr_sg0,al              ; reset character sets
  1652.         mov     chr_sg1,al
  1653.         mov     ax,offset chr_sg0       ; select character set zero
  1654.         mov     chr_set,ax
  1655.         ret
  1656. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; end of part one ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1657. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; start of part two ;;;;;;;;;;;;;;;;;;;;;;;;;;
  1658. ; Routine to set special graphics character set (used in VT52 mode).
  1659.  
  1660. chrsgs: mov     al,sgrset               ; Select "graphics" set
  1661.         jmp     chrde1                  ; Do it and return
  1662.  
  1663. ; Control-character handling routines
  1664.  
  1665. atbel:  call    vtbell                  ; Just ring bell and return
  1666.         ret
  1667.  
  1668. atbs:   cmp     dl,0                    ; Backspace. too far?
  1669.         je      atbs1                   ; e = at column 0 already
  1670.         dec     dl                      ; Backup cursor
  1671. atbs1:  call    atccpc                  ; Check range
  1672.         jmp     atscu5                  ; Set cursor and return
  1673.  
  1674. atht:   cmp     flags.vtflg,ttheath     ; Heath-19 mode?
  1675.         je      atht2                   ; e = yes. handle specially
  1676.         mov     ch,0
  1677.         mov     cl,byte ptr low_rgt
  1678.         cmp     dl,cl                   ; At or beyond last column?
  1679.         jae     atbs1                   ; Yes, check range, set cursor and ret
  1680.         mov     bh,0                    ; Make an index
  1681.         mov     bl,dl                   ; For column
  1682.         sub     cl,dl                   ; number of columns to examine
  1683. atht1:  inc     bx                      ; Tab always moves at least one space
  1684.         cmp     tabs[bx],0              ; Look for non-zero
  1685.         loopz   atht1
  1686.         mov     dl,bl                   ; Get the new row index
  1687.         jmp     atbs1                   ; Check range, set cursor, and return
  1688. atht2:  mov     dx,cursor               ; Heath-19. get cursor position
  1689.         add     dl,8                    ; tabs are every 8 columns
  1690.         and     dl,not 7                ; do modulo 8
  1691.         cmp     dl,byte ptr low_rgt     ; check against right edge
  1692.         jae     atht3                   ; ae = out of range
  1693.         jmp     atscu5                  ; set cursor and return
  1694. atht3:  test    ansflgs,decawm          ; doing line wrapping?
  1695.         jnz     atht4                   ; nz = yes. wrap to next line
  1696.         mov     dl,byte ptr low_rgt     ; else go to right margin
  1697.         jmp     atscu5                  ; set cursor and return
  1698. atht4:  inc     dh                      ; say want next line down
  1699.         xor     dl,dl                   ; and left margin
  1700.         call    atccic                  ; index check
  1701.         call    ax                      ; do any needed scrolling
  1702. atht4a: jmp     atscu5                  ; reset cursor
  1703.  
  1704. atlf:   cmp     flags.vtflg,ttheath     ; Heath-19 mode?
  1705.         je      atlf2                   ; e = yes
  1706.         test    ansflgs,anslnm          ; New-line mode?
  1707.         jz      atlf2                   ; No - just move to next line down
  1708.         mov     dl,0                    ; Yes - move to left margin also
  1709. atlf2:  inc     dh                      ; Index line down
  1710.         call    atccic                  ; Check indexing
  1711.         call    ax                      ; Call scrolling routine
  1712.         jmp     atscu5                  ; Set cursor
  1713.  
  1714. atcr:   mov     dl,0                    ; Go to left margin
  1715.         jmp     atscu5                  ; Set cursor and return
  1716.  
  1717. atff:   cmp     ttstate,offset atescf   ; parsing escape sequence?
  1718.         jne     atlf                    ; ne = no, do as line feed
  1719.         test    denyflg,200h            ; is auto Tek mode disabled?
  1720.         jnz     atlf                    ; nz = yes, treat as line feed
  1721.         call    atsc                    ; save cursor and associated data
  1722.         JMP     TEKESC                  ; Jump to Tektronix Emulator, al=FF
  1723.  
  1724. atso:   mov     ax,offset chr_sg1       ; Select set G1 and return
  1725.         mov     chr_set,ax
  1726.         ret
  1727.  
  1728. atsi:   mov     ax,offset chr_sg0       ; Select set G0 and return
  1729.         mov     chr_set,ax
  1730.         ret
  1731.  
  1732. atcan:  cmp     ttstate,offset atnrm    ; doing normal chars (vs esc seq)?
  1733.         jne     atcan1                  ; ne = no, assume esc seq
  1734.         jmp     atign                   ; ignore ~X, ~Z in normal mode
  1735. atcan1: mov     ttstate,offset atnrm    ; Reset state to "normal"
  1736.         mov     al,sgrtab+2             ; replace CAN (~X) by checkerboard
  1737.         jmp     atnrm                   ; Process char as a normal one
  1738.  
  1739. atesc:  mov     nansarg,0               ; Clear ANSI arguments
  1740.         mov     al,0
  1741.         mov     cx,lansarg
  1742.         mov     di,offset ansargs
  1743.         push    es
  1744.         push    ds
  1745.         pop     es                      ; use datas segment for es:di below
  1746.         cld                             ; set direction forward
  1747.         rep     stosb
  1748.         pop     es
  1749.         and     escdec,not decmode      ; Clear "DEC modes" flag
  1750.         mov     h19mod,0                ; clear Heath-19 mode flag
  1751.         mov     ttstate,offset atescf   ; Next state is escape follower
  1752.         ret
  1753.  
  1754. atescf: cmp     flags.vtflg,ttvt100     ; VT100?
  1755.         jne     atv52f                  ; ne = not VT100, try others
  1756. atescf0:mov     cx,lansesc              ; Escape follower - get table length
  1757.         mov     di,offset ansesc        ; Point di at table
  1758.         push    es
  1759.         push    ds
  1760.         pop     es                      ; use datas segment for es:di below
  1761.         cld                             ; set direction forward
  1762.         repne   scasb                   ; Find it
  1763.         pop     es
  1764.         je      atescf1                 ; Found - now go do something with it
  1765.         jmp     atnorm                  ; Not there - just ignore it
  1766.  
  1767. atescf1:mov     di,lansesc - 1          ; Compute word index into jump table
  1768.         sub     di,cx
  1769.         shl     di,1
  1770.         jmp     ansejt[di]              ; Dispatch to the routine
  1771.  
  1772. atv52f: cmp     flags.vtflg,ttheath     ; Heath-19?
  1773.         je      ath19f                  ; e = yes. Use Heath esc seqs
  1774.         mov     ttstate,offset atnrm    ; Assume state "normal" on return
  1775.         mov     cx,lv52esc              ; Get table length
  1776.         mov     di,offset v52esc        ; Point di at table
  1777.         push    es
  1778.         push    ds
  1779.         pop     es                      ; use datas segment for es:di below
  1780.         cld                             ; set direction forward
  1781.         repne   scasb                   ; Find it
  1782.         pop     es
  1783.         je      atv52f1                 ; Found - do something with it
  1784.         ret                             ; Not there - just ignore it
  1785.  
  1786. atv52f1:mov     di,lv52esc - 1          ; Compute word index into jump table
  1787.         sub     di,cx
  1788.         shl     di,1
  1789.         jmp     v52ejt[di]              ; Dispatch to the routine
  1790.  
  1791. ath19f: mov     ttstate,offset atnrm    ; Assume state "normal" on return
  1792.         test    ansflgs,decanm          ; ansi mode?
  1793.         jnz     atescf0                 ; nz = yes, use ansi table
  1794.         mov     cx,lh19esc              ; Get table length
  1795.         mov     di,offset h19esc        ; Point di at table
  1796.         push    es
  1797.         push    ds
  1798.         pop     es                      ; use datas segment for es:di below
  1799.         cld                             ; set direction forward
  1800.         repne   scasb                   ; Find it
  1801.         pop     es
  1802.         je      ath19f1                 ; Found - do something with it
  1803.         ret                             ; Not there - just ignore it
  1804.  
  1805. ath19f1:mov     di,lh19esc - 1          ; Compute word index into jump table
  1806.         sub     di,cx
  1807.         shl     di,1
  1808.         jmp     h19ejt[di]              ; Dispatch to the routine
  1809.  
  1810. at9bh:  call    atesc                   ; 9bH char (ANSI CSI == ESC [)
  1811.         mov     ttstate,offset atpaa    ; next state is parse ansi sequences
  1812.         ret
  1813.  
  1814. ; Escape follower routines.
  1815.  
  1816. atcsi:  mov     ttstate,offset atpaa    ; Next state is parse ansi args
  1817.         ret
  1818.  
  1819. atpaa:  test    al,80h                  ; high bit set?
  1820.         jz      atpaa6                  ; z = no
  1821.         and     al,7fh                  ; strip high bit
  1822.         cmp     al,' '                  ; control code remainder?
  1823.         jae     atpaa6                  ; ae = no, use 7 bit result
  1824.         mov     ttstate,offset atnrm    ; reset state to normal text
  1825.         jmp     atctrl                  ; execute 7 bit control code
  1826. atpaa6: cmp     al,'0'                  ; A digit?
  1827.         jb      atpaa1                  ; No - just ignore it
  1828.         cmp     al,'9'                  ; Maybe - A separator or final char?
  1829.         ja      atpaa2                  ; Perhaps - go check it out
  1830.         mov     cl,al                   ; A digit - convert ASCII to binary
  1831.         sub     cl,'0'
  1832.         mov     ch,0
  1833.         mov     bl,nansarg              ; put index in bx [dlk]
  1834.         xor     bh,bh
  1835.         mov     al,ansargs[bx]          ; Pick up what we've done so far [dlk]
  1836.         shl     al,1                    ; multiply by 10.  2 * al
  1837.         mov     ah,al                   ; save
  1838.         shl     al,1                    ; 4 * al
  1839.         shl     al,1                    ; 8 * al
  1840.         add     al,ah                   ; 10 * al
  1841.         mov     ah,0                    ; clear high field
  1842.         add     ax,cx                   ; add in this digit [dlk]
  1843.         cmp     ax,0feh                 ; max value is 0ffh [dlk]
  1844.         jbe     atpaa0                  ; be = ok [dlk]
  1845.         mov     al,0ffh                 ; set to max value [dlk]
  1846. atpaa0: mov     ansargs[bx],al          ; Put result back for next time [dlk]
  1847. atpaa1: ret                             ; And return
  1848.  
  1849. atpaa2: cmp     al,'?'                  ; The deadly question mark?
  1850.         jne     atpaa2a                 ; No - check further
  1851.         or      escdec,decmode          ; Yes - say DEC modes are coming
  1852.         ret                             ; And return
  1853. atpaa2a:cmp     al,'>'                  ; Heath private mode?
  1854.         jne     atpaa3                  ; ne = no
  1855.         cmp     flags.vtflg,ttheath     ; emulating a Heath-19?
  1856.         jne     atpaa3                  ; ne = no, ignore this sequence
  1857.         mov     h19mod,1                ; say Heath mode sequence follows
  1858.         ret
  1859.  
  1860. atpaa3: cmp     al,';'                  ; Argument separator?
  1861.         jne     atpaa4                  ; No - check for final char
  1862.         mov     al,nansarg              ; Get argument index
  1863.         inc     al                      ; Bump it
  1864.         cmp     al,lansarg              ; Too many?
  1865.         jl      atpa3a                  ; l = no, continue
  1866.         mov     ttstate,offset atnrm    ; Reset state to "normal"
  1867.         ret                             ; and pretend all is well
  1868. ; [jrd] jmp     atcan                   ; Yes - abandon sequence on error
  1869. atpa3a: mov     nansarg,al              ; Save it
  1870.         ret
  1871.  
  1872. atpaa4: mov     cx,lanstab
  1873.         mov     di,offset anstab        ; Look for it in the table
  1874.         push    es
  1875.         push    ds
  1876.         pop     es                      ; use datas segment for es:di below
  1877.         cld                             ; set direction forward
  1878.         repne   scasb
  1879.         pop     es
  1880.         je      atpaa5                  ; Found it - go dispatch
  1881.         cmp     al,40h                  ; in range for a legal terminator?
  1882.         jb      atpaa4a                 ; b = not in range, ignore
  1883.         cmp     al,7eh                  ; other end of the range
  1884.         ja      atpaa4a                 ; a = out of range, ignore
  1885.                                         ; in range, absorb and become normal
  1886.         mov     ttstate,offset atnrm    ; Put state back to normal
  1887. atpaa4a:ret                             ; Just return if it is unknown
  1888.  
  1889. atpaa5: mov     ttstate,offset atnrm    ; Put state back to normal
  1890.         mov     di,lanstab - 1          ; Compute word index into jump table
  1891.         sub     di,cx
  1892.         shl     di,1
  1893.         jmp     ansjmp[di]              ; Off into the wild blue
  1894.  
  1895. atind:  inc     dh                      ; Index - move cursor down one
  1896. atind1: call    atccic                  ; Check cursor position
  1897.         call    ax                      ; Scroll if necessary
  1898.         mov     ttstate,offset atnrm    ; Reset state
  1899.         jmp     atscu5                  ; Set cursor, etc. and return
  1900.  
  1901. atnel:  mov     dl,0                    ; Next line - sort of like CRLF
  1902.         inc     dh                      ; ... all in one command
  1903.         jmp     atind1                  ; Check cursor, etc., and return
  1904.  
  1905. atri:   dec     dh                      ; Reverse index
  1906.         jmp     atind1                  ; Check cursor, etc., and return
  1907.  
  1908. athts:  call    atccpc                  ; Make sure we have valid column number
  1909.         mov     dh,0                    ; Zap row
  1910.         mov     al,0FFH                 ; Indicates a tab stop
  1911.         mov     di,dx                   ; Dumb specialized registers
  1912.         mov     tabs[di],al             ; Store it
  1913.         jmp     atnorm                  ; Reset state and return
  1914.  
  1915. atsc:   mov     si,offset curattr       ; Save cursor, attribute, char set etc
  1916.         mov     di,offset savecu        ; Place to save the stuff
  1917.         mov     cx,lsavecu              ; Length of save area
  1918.         push    es                      ; save es
  1919.         push    ds
  1920.         pop     es                      ; set es to datas segment
  1921.         cld
  1922.         rep     movsb                   ; Save it
  1923.         pop     es
  1924.         mov     cl,ansflgs              ; Save a copy of the flags
  1925.         mov     savflgs,cl
  1926.         jmp     atnorm                  ; Reset state and return
  1927.  
  1928. atrc:   mov     si,offset savecu        ; Restore cursor, attributes, etc.
  1929.         mov     di,offset curattr       ; Where stuff goes
  1930.         mov     cx,lsavecu              ; Length of save area
  1931.         push    es                      ; save es
  1932.         push    ds
  1933.         pop     es                      ; set es to datas segment
  1934.         cld
  1935.         rep     movsb                   ; Put the stuff back
  1936.         pop     es
  1937.         mov     al,savflgs              ; Get saved flags
  1938.         xor     al,ansflgs              ; Exclusive-or with current flags
  1939.         test    al,decscnm              ; Did screen mode change?
  1940.         jz      atrc1                   ; No, just reset saved flags and leave
  1941.         mov     ah,curattr              ; Get cursor attribute that was saved
  1942.         call    brkatt                  ; Break into background & extra stuff
  1943.         rol     ah,1                    ; Reverse the background
  1944.         rol     ah,1                    ; Reverse the background
  1945.         rol     ah,1                    ; Reverse the background
  1946.         rol     ah,1                    ; Reverse the background
  1947.         call    addatt                  ; Put it all back together
  1948.         mov     curattr,ah              ; Store
  1949. atrc1:  mov     al,ansflgs              ; Reset flags in case called again
  1950.         and     al, not(decckm+deckpam+decom)  ; remove old bits [dlk]
  1951.         and     savflgs,(decckm+deckpam+decom) ; remove all but new bits [dlk]
  1952.         or      al,savflgs              ; restore saved bits [dlk]
  1953.         mov     ansflgs,al              ; update these flags [dlk]
  1954.         mov     savflgs,al
  1955.         mov     dx,cursor               ; Get cursor
  1956.         mov     kbiflg,0                ; Don't bother them with beeps here
  1957.         call    atscu5                  ; Set cursor
  1958.         jmp     atnorm                  ; Reset state and return
  1959.  
  1960. atkpam: or      ansflgs,deckpam         ; Turn on the bit
  1961.         mov     al,yflags
  1962.         call    telmsy                  ; inform msy of new state
  1963.         jmp     atnorm                  ; Reset state and return
  1964.  
  1965. atkpnm: and     ansflgs,not deckpam     ; Turn off the bit
  1966.         mov     al,yflags
  1967.         call    telmsy                  ; inform msy of new state
  1968.         jmp     atnorm                  ; Reset state and return
  1969.  
  1970. atris:  call    atreset                 ; Reset everything
  1971.         jmp     atnorm                  ; And state too, return, etc
  1972.  
  1973. atsg0:  mov     ttstate,offset atsg01   ; Setup to get last character
  1974.         ret
  1975.  
  1976. atsg01: call    atscs                   ; Get code for character set
  1977.         mov     chr_sg0,al              ; Store it
  1978.         jmp     atnorm                  ; Reset state etc. and return
  1979.  
  1980. atsg1:  mov     ttstate,offset atsg11   ; Setup to get last character
  1981.         ret
  1982.  
  1983. atsg11: call    atscs                   ; Get code for character set
  1984.         mov     chr_sg1,al              ; Store it
  1985.         jmp     atnorm                  ; Reset state etc. and return
  1986.  
  1987. atscs:  cmp     al,'A'                  ; UK ASCII set?
  1988.         jne     atscs1                  ; No
  1989.         mov     al,ukset                ; Yes - give them that and return
  1990.         ret
  1991.  
  1992. atscs1: cmp     al,'B'                  ; US ASCII set?
  1993.         jne     atscs3                  ; No
  1994. atscs2: mov     al,ascset               ; Yes - give them that and return
  1995.         ret
  1996.  
  1997. atscs3: cmp     al,'0'                  ; Special graphics set?
  1998.         jne     atscs4                  ; ne = no
  1999.         mov     al,sgrset               ; Yes - say that's what it is
  2000.         ret
  2001.  
  2002. atscs4: cmp     al,'1'                  ; alt char ROM, std char set?
  2003.         jne     atscs5                  ; ne = no
  2004.         mov     al,alcset               ; use Alternate character set
  2005.         ret
  2006.  
  2007. atscs5: cmp     al,'2'                  ; alt char ROM, special graphics?
  2008.         jne     atscs2                  ; ne = no, use US ASCII
  2009.         mov     al,sgrset               ; set graphics
  2010.         ret
  2011.  
  2012.                                         ; ESC # Pn  series
  2013. atsdhl: mov     ttstate,offset atsdbl   ; set up to parse argument
  2014.         ret
  2015. atsdbl: cmp     al,'3'                  ; Double high lines. Top half?
  2016.         je      atsdh2                  ; e = yes
  2017.         cmp     al,'4'                  ; bottom half?
  2018.         je      atsdh2                  ; e = yes
  2019.         cmp     al,'5'                  ; restore line to single width?
  2020.         je      atsdh1                  ; e = yes
  2021.         cmp     al,'6'                  ; double width single height?
  2022.         je      atsdh2                  ; e = yes
  2023.         cmp     al,'8'                  ; screen alignment?
  2024.         je      atsdh8                  ; e = yes
  2025.         jmp     atnorm                  ; else ignore
  2026. atsdh1: call    linesgl                 ; set line to single width
  2027.         jmp     atnorm
  2028. atsdh2: call    linedbl                 ; expand the line to double width
  2029.         jmp     atnorm                  ; set state to normal and ret
  2030. atsdh8: call    atalign                 ; do screen alignment
  2031.         jmp     atnorm
  2032. atpriv: mov     ttstate,offset atnorm   ; ignore next char
  2033.         ret                             ; and return to normal afterward
  2034.  
  2035. atalign proc    near                    ; Fill screen with 'E'
  2036.         call    atreset                 ; clear system
  2037.         or      ansflgs,decawm          ; set wrap
  2038.         mov     cl,byte ptr low_rgt     ; number of columns-1
  2039.         inc     cl
  2040.         mov     al,byte ptr low_rgt+1   ; number of rows-1
  2041.         inc     al
  2042.         mul     cl                      ; ax = number of chars on screen
  2043.         mov     cx,ax
  2044. atalig1:push    cx
  2045.         mov     al,'E'                  ; write screen full of E's
  2046.         call    atnrm                   ; write the 'E'
  2047.         pop     cx
  2048.         loop    atalig1                 ; cx times
  2049.         ret
  2050. atalign endp
  2051.  
  2052. ; This routine may be used to repeat a call to a selected action routine
  2053. ; for all of the ANSI parameters given in a call.   When the action routine
  2054. ; is called, si will contain the index for the current ANSI parameter (i.e.,
  2055. ; the current ANSI parameter may be gotten using ansargs[si] for an effective
  2056. ; address).     The action routine may modify any ACs it wants, but cx, si,
  2057. ; and di are preserved over the call to the action routine, so these may
  2058. ; not be used for building return values for the original caller.   Note that
  2059. ; if there are no ANSI parameters, the effect is the same as if one ANSI
  2060. ; parameter with a value of zero was given.
  2061. ;
  2062. ; Call:         di/     offset of action routine in code seqment
  2063. ;
  2064.  
  2065. atreps: mov     cl,nansarg              ; Pick up number of parameters
  2066.         inc     cl                      ; Zero parms is same as 1 zero parm
  2067.         mov     ch,0
  2068.         mov     si,0                    ; Init parm index
  2069. atrep1: push    cx                      ; Save important acs
  2070.         push    si
  2071.         push    di
  2072.         call    di                      ; Call indicated routine
  2073.         pop     di                      ; Restore acs
  2074.         pop     si
  2075.         pop     cx
  2076.         inc     si                      ; Advance to next parameter
  2077.         loop    atrep1                  ; Loop for all
  2078.         ret                             ; And return
  2079.  
  2080.  
  2081. ; Final char (ANSI) routines.
  2082.  
  2083. atcup:  mov     dh,ansargs              ; Get the two arguments
  2084.         mov     dl,ansargs+1
  2085.         cmp     dh,0                    ; Zero line number?
  2086.         jne     atcup1                  ; No - continue
  2087.         mov     dh,1                    ; Yes - default to one
  2088. atcup1: cmp     dl,0                    ; Ditto for row
  2089.         jne     atcup2
  2090.         mov     dl,1
  2091. atcup2: dec     dh                      ; Now normalize
  2092.         dec     dl
  2093.         test    ansflgs,decom           ; Origin mode?
  2094.         jz      atcup4                  ; No - skip this stuff
  2095.         add     dh,mar_top              ; Yes - it was relative to top margin
  2096.         jno     atcup4                  ; If no overflow, continue
  2097.         mov     dh,byte ptr low_rgt+1   ; Otherwise just set to screen bottom
  2098. atcup4: cmp     dh,byte ptr low_rgt+1   ; going to 25th line? [hlk]
  2099.         jbe     atcup5                  ; be = no [dlk]
  2100.         cmp     flags.vtflg,ttheath     ; emulating a Heath-19?
  2101.         jne     atcup6                  ; ne = no [hlk]
  2102.         cmp     h19l25,0                ; Heath 25th line enabled?
  2103.         je      atcup5                  ; e = no
  2104. atcup6: mov     dh,byte ptr low_rgt+1   ; bottom normal line
  2105.         inc     dh                      ; the 25th line
  2106.         jmp     atscu4                  ; set cursor position and return
  2107. atcup5: call    atccpc                  ; Check position
  2108.         jmp     atscu5                  ; Set cursor position and return
  2109.  
  2110. atcuarg:mov     al,ansargs              ; Get a cursor move argument
  2111.         cmp     al,0                    ; Zero?
  2112.         jne     atcua1                  ; No - return
  2113.         mov     al,1                    ; Yes - default to one
  2114. atcua1: ret                             ; Return
  2115.                                         ; Disallow movement to 25th line
  2116. atcuu:  call    atcuarg                 ; Get cursor move argument in al
  2117.         sub     dh,al                   ; Compute new cursor position
  2118.         jnc     atcuu1                  ; nc = ok [dlk]
  2119.         xor     dh,dh                   ; overflow, restrict range. [dlk]
  2120. atcuu1: call    atccic                  ; check indexing, ignore action in ax
  2121.         jmp     atscu5                  ; set the cursor at its new position
  2122.  
  2123. atcud:  call    atcuarg                 ; Get the argument
  2124.         add     dh,al                   ; Compute new cursor position
  2125.         jnc     atcud1                  ; nc = ok [dlk]
  2126.         mov     dh,byte ptr low_rgt+1   ; default bottom [dlk]
  2127. atcud1: call    atccic                  ; check indexing, ignore action in ax
  2128.         jmp     atscu5                  ; set the cursor at its new position
  2129.  
  2130.                                         ; Allow horiz movement on 25th line
  2131. atcuf:  call    atcuarg                 ; Get the argument
  2132.         add     dl,al                   ; Compute new cursor position
  2133.         jnc     atcup4                  ; If no carry, continue [dlk]
  2134.         mov     dl,byte ptr low_rgt     ; Else set to right margin
  2135.         jmp     atcup4                  ; Check/set cursor, return
  2136.  
  2137. atcub:  call    atcuarg                 ; Get the argument
  2138.         sub     dl,al                   ; Compute new cursor position
  2139.         jnc     atcup4                  ; If no carry, continue [dlk]
  2140.         mov     dl,0                    ; Else set to left margin
  2141.         jmp     atcup4                  ; Check/set cursor, return
  2142.  
  2143. ated:   mov     di,offset ated0         ; Routine to process parm
  2144.         call    atreps                  ; Do all selected parms
  2145.         ret
  2146.  
  2147. ated0:  cmp     ansargs[si],0           ; Was arg zero?
  2148.         jne     ated2                   ; No - continue
  2149.         mov     ax,dx               ; Yes - erase from cursor to end of screen
  2150.         cmp     dx,0                    ; cursor at home position?
  2151.         je      atedcom                 ; e = yes, roll screen before clear
  2152.         push    dx                      ; save dx
  2153.         mov     bl,dh                   ; get row number
  2154.         xor     bh,bh
  2155.         cmp     linetype [bx],0         ; single width line?
  2156.         je      ated0a                  ; e = yes
  2157.         shl     dl,1                    ; physical column is twice logical
  2158. ated0a: or      dl,dl                   ; starting at left margin?
  2159.         je      ated0b                  ; e = yes, this goes to single width
  2160.         inc     bl                      ; else start on next line
  2161. ated0b: cmp     bl,byte ptr low_rgt+1   ; at the end of the screen?
  2162.         ja      ated0c                  ; a = yes, stop singling-up
  2163.         mov     byte ptr linetype [bx],0 ; set to single width
  2164.         inc     bx
  2165.         jmp     short ated0b            ; loop, reset lines to end of screen
  2166. ated0c: mov     bx,low_rgt              ; erase from cursor to end of screen
  2167.         mov     bl,crt_cols
  2168.         dec     bl                      ; do physical screen width
  2169.         call    vtsclr                  ; Clear it
  2170.         pop     dx                      ; restore dx
  2171. ated1:  ret
  2172.  
  2173. ated2:  cmp     ansargs[si],1           ; Was arg one?
  2174.         jne     ated3                   ; No - continue
  2175.         mov     ax,0                    ; Yes -  erase from start of screen
  2176.                                         ;  to cursor, inclusive
  2177.         xor     bx,bx                   ; start at top row (0)
  2178. ated2b: cmp     bl,dh                   ; check rows from the top down
  2179.         jae     ated2c                  ; ae = at or below current line
  2180.         mov     byte ptr linetype [bx],0; set line to single width
  2181.         inc     bx                      ; inc row
  2182.         jmp     short ated2b            ; look at next line
  2183. ated2c: or      dl,dl                   ; at left margin of current line?
  2184.         jne     ated2d                  ; ne = no, leave line width intact
  2185.         mov     byte ptr linetype [bx],0 ; convert to single width
  2186. ated2d: mov     bl,dh                   ; get row number
  2187.         xor     bh,bh
  2188.         cmp     linetype [bx],0         ; single width line?
  2189.         je      ated2a                  ; e = yes
  2190.         shl     dl,1                    ; physical column is twice logical
  2191. ated2a: mov     bx,dx                   ; cursor position to bx
  2192.         call    vtsclr                  ; Clear it
  2193.         ret
  2194.  
  2195. ated3:  cmp     ansargs[si],2           ; Was arg two?
  2196.         jne     ated1                   ; ne = no, else erase entire screen
  2197.                                         ; entry to roll screen before erasing
  2198. atedcom:mov     al,byte ptr low_rgt+1   ; number of lines on screen
  2199.         mov     scroll,al
  2200.         call    atscru                  ; scroll them up before erasure
  2201.                                         ; removes double w/h lines too.
  2202.         mov     ax,0                    ; erase from here (home)
  2203.         mov     bx,low_rgt
  2204.         mov     bl,crt_cols
  2205.         dec     bl                      ; physical width (to here)
  2206.         call    vtsclr                  ; clear screen
  2207.         ret
  2208.  
  2209. atel:   mov     di,offset atel0         ; Get routine to call
  2210.         call    atreps                  ; Repeat for all parameters
  2211.         ret
  2212.  
  2213. atel0:  cmp     ansargs[si],0           ; Was arg zero?
  2214.         jne     atel2                   ; No - continue
  2215.         mov     ax,dx                   ; Yes - erase from cursor
  2216.         mov     bh,dh                   ; ...to end of line, inclusive
  2217.         push    bx
  2218.         mov     bl,bh                   ; get row
  2219.         mov     bh,0
  2220.         cmp     linetype [bx],0         ; single width line?
  2221.         je      atel0a                  ; e = yes
  2222.         shl     al,1                    ; physical column is twice logical
  2223. atel0a: pop     bx
  2224.         mov     bl,byte ptr low_rgt
  2225.         call    vtsclr                  ; Clear it
  2226. atel1:  ret
  2227.  
  2228. atel2:  cmp     ansargs[si],1           ; Was arg one?
  2229.         jne     atel3                   ; No - continue
  2230.         mov     ah,dh                   ; Yes -  erase from start of line
  2231.         mov     al,0
  2232.         mov     bx,dx                   ; ...to cursor, inclusive
  2233.         push    bx
  2234.         mov     bl,dh                   ; get row
  2235.         mov     bh,0
  2236.         cmp     linetype [bx],0         ; single width line?
  2237.         pop     bx                      ; pop does not affect flags
  2238.         je      atel2a                  ; e = yes
  2239.         shl     bl,1                    ; physical column is twice logical
  2240. atel2a:
  2241.         call    vtsclr                  ; Clear it
  2242.         ret
  2243.  
  2244. atel3:  cmp     ansargs[si],2           ; Was arg two?
  2245.         jne     atel1                   ; No - ignore it
  2246.         mov     ah,dh                   ; Yes - erase entire line
  2247.         mov     al,0
  2248.         mov     bh,dh
  2249.         mov     bl,byte ptr low_rgt
  2250.         mov     bl,crt_cols
  2251.         dec     bl                      ; physical line
  2252.         call    vtsclr                  ; Clear it
  2253.         ret
  2254.  
  2255. atsgr:  mov     ah,curattr              ; Get current cursor attribute
  2256.         call    brkatt                  ; Break it apart
  2257.         mov     di,offset atsgr1        ; Routine to call
  2258.         call    atreps                  ; Repeat for all parms
  2259.         call    addatt                  ; Put the attributes back together
  2260.         mov     curattr,ah              ; Store
  2261.         ret
  2262.  
  2263. atsgr1: mov     bl,ansargs[si]          ; Fetch an argument
  2264.         cmp     bl,0                    ; Zero?
  2265.         jne     atsgr2                  ; No
  2266.         mov     al,0                    ; Yes - clear the "extras"
  2267.         mov     ah,scbattr              ; And reset background
  2268.         and     ah,77h                  ; clear blink/bold here
  2269.         mov     video_state,0           ; say normal video now
  2270.         ret
  2271.  
  2272. atsgr2: cmp     bl,1                    ; One?
  2273.         jne     atsgr3                  ; No
  2274.         or      al,att_intensity        ; Yes - set bold
  2275.         ret
  2276.  
  2277. atsgr3: cmp     bl,4                    ; Four? Underline. Mods by [jrd]
  2278.         jne     atsgr4                  ; ne = no
  2279.         or      al,att_underline        ; Yes, set underscore
  2280.         cmp     crt_mode,7              ; monochrome display adapter mode?
  2281.         je      atsgr3a                 ; e = yes. Otherwise reverse video
  2282.                         ; use reversed video rather than blue on black
  2283.         and     al,not att_underline    ; clear underline and
  2284.         rol     ah,1                    ; reverse the colors
  2285.         rol     ah,1
  2286.         rol     ah,1
  2287.         rol     ah,1
  2288. atsgr3a:ret
  2289.  
  2290. atsgr4: cmp     bl,5                    ; Five?
  2291.         jne     atsgr5                  ; No
  2292.         or      al,att_blink            ; Yes - set blink
  2293.         ret
  2294.  
  2295. atsgr5: cmp     bl,7                    ; Seven?
  2296.         jne     atsgr6                  ; No - just ignore it
  2297.         cmp     video_state,0           ; is video normal?
  2298.         jne     atsgr6                  ; ne = no, reversed already, ignore
  2299.         rol     ah,1                    ; reverse the colors
  2300.         rol     ah,1
  2301.         rol     ah,1
  2302.         rol     ah,1
  2303.         mov     video_state,1           ; say reversed now
  2304.         ret
  2305.  
  2306. atsgr6: cmp     bl,30                   ; ANSI color series?
  2307.         jb      atsgrx                  ; b = no
  2308.         cmp     bl,37                   ; foreground set (30-37)?
  2309.         ja      atsgr7                  ; a = no, try background set
  2310.         sub     bl,30                   ; take away the bias
  2311.         and     ah,not 07H              ; clear foreground bits
  2312.         test    bl,1                    ; ANSI red?
  2313.         jz      atsgr6a                 ; z = no
  2314.         or      ah,4                    ; IBM red foreground bit
  2315. atsgr6a:test    bl,2                    ; ANSI & IBM green?
  2316.         jz      atsgr6b                 ; z = no
  2317.         or      ah,2                    ; IBM green foreground bit
  2318. atsgr6b:test    bl,4                    ; ANSI blue?
  2319.         jz      atsgr6c                 ; z = no
  2320.         or      ah,1                    ; IBM blue foreground bit
  2321. atsgr6c:ret
  2322.  
  2323. atsgr7: cmp     bl,40                   ; background color set?
  2324.         jb      atsgrx                  ; b = no
  2325.         cmp     bl,47                   ; background set is 40-47
  2326.         ja      atsgrx                  ; nb = no, not a color command
  2327.         sub     bl,40                   ; take away the bias
  2328.         and     ah,not 70H              ; clear background bits
  2329.         test    bl,1                    ; ANSI red?
  2330.         jz      atsgr7a                 ; z = no
  2331.         or      ah,40h                  ; IBM red background bit
  2332. atsgr7a:test    bl,2                    ; ANSI & IBM green?
  2333.         jz      atsgr7b                 ; z = no
  2334.         or      ah,20h                  ; IBM green background bit
  2335. atsgr7b:test    bl,4                    ; ANSI blue?
  2336.         jz      atsgrx                  ; z = no
  2337.         or      ah,10h                  ; IBM blue background bit
  2338.  
  2339. atsgrx: ret
  2340.  
  2341. attbc:  call    atccpc                  ; Make sure cursor is kosher
  2342.         mov     di,offset attbc0        ; Routine to call
  2343.         call    atreps                  ; Do for all parms
  2344.         ret
  2345.  
  2346. attbc0: cmp     ansargs[si],0           ; Was argument zero?
  2347.         jne     attbc2                  ; No - check further
  2348.         mov     dh,0                    ; Zap row for indexing
  2349.         mov     di,dx
  2350.         mov     tabs[di],0              ; clear tab stop
  2351. attbc1: ret
  2352.  
  2353. attbc2: cmp     ansargs[si],3           ; Was arg 3 (clear all tab stops)?
  2354.         jne     attbc1                  ; No - just ignore it
  2355.         mov     cx,swidth               ; Get ready to zap swidth columns
  2356.         mov     di,offset tabs          ; Point to the tab stop table
  2357.         mov     al,0                    ; zero indicates no tab stop
  2358.         push    es                      ; save es
  2359.         push    ds
  2360.         pop     es                      ; use datas segment for es:di below
  2361.         cld                             ; set direction forward
  2362.         rep     stosb                   ; Blit full of zeros
  2363.         pop     es
  2364.         ret
  2365.  
  2366. atstbm: mov     al,ansargs              ; Get the two line number args
  2367.         mov     ah,ansargs+1
  2368.         cmp     al,0                    ; Was first zero?
  2369.         jne     atstb1                  ; No - continue
  2370.         mov     al,1                    ; Yes - default is one
  2371. atstb1: cmp     ah,0                    ; Was second zero?
  2372.         jne     atstb2                  ; No - continue
  2373.         mov     ah,byte ptr low_rgt+1   ; Yes - default is last line on screen
  2374.         inc     ah
  2375. atstb2: dec     al                      ; Normalize to our coord. system
  2376.         dec     ah
  2377.         cmp     ah,al                   ; Is size of region at least two lines?
  2378.         jbe     atstb3                  ; be = if not, indicate an error
  2379.         cmp     al,0                    ; Check against screen limits
  2380.         jl      atstb3
  2381.         cmp     ah,byte ptr low_rgt+1
  2382.         ja      atstb3
  2383.         mov     mar_top,al              ; Set the limits
  2384.         mov     mar_bot,ah
  2385.         mov     dx,0                    ; Home cursor
  2386.         call    atccpc                  ; Check cursor (get it inside window)
  2387.         jmp     atscu5                  ; Set cursor position and return
  2388.  
  2389. atstb3: ret                             ; ignore bad requests
  2390. ;;;     jmp     atcan                   ; Indicate error and return
  2391.  
  2392. atda:   cmp     ansargs,0               ; Was argument zero?
  2393.         je      decid                   ; Yes - send the i.d. string
  2394.         ret                             ; No - only an echo
  2395. at52id: mov     ttstate,offset atnrm    ; ensure state is correct
  2396. decid:  mov     cx,20                   ; assumed length of asciiz string
  2397.         mov     si,offset dastr         ; Point to the string
  2398.         cmp     flags.vtflg,ttvt100     ; VT100?
  2399.         je      decid1                  ; e = yes
  2400.         mov     si,offset v52str        ; No - try VT52 i.d.
  2401.         cmp     flags.vtflg,ttvt52      ; Heath-19 mode?
  2402.         je      decid1                  ; e = yes
  2403.         mov     si,offset h19str        ; say Heath-19
  2404. decid1: cld
  2405.         lodsb                           ; Get a byte
  2406.         cmp     al,0                    ; end of string?
  2407.         je      decid2                  ; e = yes
  2408.         push    cx                      ; Save the important registers
  2409.         push    si
  2410.         call    prtbout                 ; Send it to port with no local echo
  2411.         pop     si
  2412.         pop     cx
  2413.         loop    decid1                  ; Loop for all characters
  2414. decid2: ret
  2415.  
  2416. atll:   mov     di,offset atleds        ; Get pointer to routine to call
  2417.         call    atreps                  ; Repeat for selective parameters
  2418.         ret
  2419.  
  2420. atleds: cmp     ansargs[si],0           ; Zero argument?
  2421.         jne     atled3                  ; No - check further
  2422.         mov     cx,4                    ; Reset the "LEDs"
  2423.         mov     al,led_off              ; to all off
  2424.         mov     di,offset ansleds+6     ; Point to the "LEDs"
  2425.         push    es                      ; save es
  2426.         push    ds
  2427.         pop     es                      ; make es:di point to datas seg
  2428.         cld                             ; move forward
  2429.         rep     stosb
  2430.         pop     es
  2431. atled1: call    disleds                 ; Update "LEDs" display and return
  2432. atled2: ret
  2433.  
  2434. atled3: mov     al,ansargs[si]          ; Get the argument
  2435.         cmp     al,1                    ; Must be .GE. 1
  2436.         jb      atled2                  ; If not just ignore it. [dlk]
  2437.         cmp     al,4                    ; Must be .LE. 4
  2438.         ja      atled2                  ; Ignore if not so. [dlk]
  2439.         dec     al                      ; Zero base it
  2440.         cbw                             ; Convert to index in ax
  2441.         mov     di,ax                   ; Dumb specialized registers
  2442.         add     al,'1'                  ; add ascii offset for digit
  2443.         mov     ansleds[di+6],al        ; Turn the "LED" on by storing digit
  2444.         jmp     atled1                  ; Update display and return
  2445.  
  2446. atreqt: cmp     ansargs,0               ; Want report?
  2447.         je      atreq1                  ; Yes - give report
  2448.         cmp     ansargs,1               ; Want report?
  2449.         je      atreq1                  ; Yes - give the report
  2450.         ret                             ; Gee, must have been an echo
  2451.  
  2452. atreq1: mov     al,escape               ; Send an escape to start off
  2453.         call    prtbout
  2454.         mov     al,'['                  ; Then one of these
  2455.         call    prtbout
  2456.         mov     al,'3'                  ; We only report on request
  2457.         cmp     ansargs,0               ; was argument a zero?
  2458.         jne     atreq1a                 ; ne = no
  2459.         mov     al,'2'                  ; yes
  2460. atreq1a:call    prtbout
  2461.         mov     al,';'                  ; Separate
  2462.         call    prtbout
  2463.         mov     bl,parcode              ; Get the parity code
  2464.         mov     bh,0
  2465.         mov     al,partab[bx]           ; Get VT100 parity code
  2466.         push    ax                      ; save parity code
  2467.         call    prtnout                 ; Send number to the port.
  2468.         mov     al,';'                  ; Separate
  2469.         call    prtbout
  2470.         mov     al,'2'                  ; Assume 7 data bits
  2471.         pop     bx                      ; get parity code into bl
  2472.         cmp     bl,1                    ; is parity none?
  2473.         jne     atreq2                  ; ne = no, so 7 data bits
  2474.         test    flags.remflg,d8bit      ; 8 bit display?
  2475.         jz      atreq2                  ; z = no
  2476.         mov     al,'1'                  ; must be eight
  2477. atreq2: call    prtbout                 ; Send it to the port
  2478.         mov     al,';'                  ; Separate
  2479.         call    prtbout
  2480.         mov     bl,baudidx              ; Baud rate index
  2481.         mov     bh,0
  2482.         mov     al,baudtab[bx]          ; Get DEC baud rate code
  2483.         push    ax
  2484.         call    prtnout                 ; Send it to the port
  2485.         mov     al,';'                  ; Separate
  2486.         call    prtbout                 ; Send it to the port
  2487.         pop     ax
  2488.         call    prtnout                 ; Send it to the port
  2489.         mov     al,';'                  ; Separate
  2490.         call    prtbout
  2491.         mov     al,'1'                  ; Clock rate multiplier is always 1
  2492.         call    prtbout
  2493.         mov     al,';'                  ; Separate (gasp - for the last time)
  2494.         call    prtbout
  2495.         mov     al,'0'                  ; Flags are always zero (no STP)
  2496.         call    prtbout
  2497.         mov     al,'x'                  ; Finally, say what this all was
  2498.         call    prtbout
  2499.         ret
  2500.  
  2501. atdsr:  mov     di,offset atdsr1        ; Routine to call
  2502.         call    atreps                  ; Do for all parms
  2503.         ret
  2504.  
  2505. atdsr1: cmp     ansargs[si],5           ; Want status?
  2506.         je      rpstat                  ; Yes - report status
  2507.         cmp     ansargs[si],6           ; Want cursor position?
  2508.         je      rpcup                   ; Yes - do it
  2509.         cmp     ansargs[si],15          ; Printer status?
  2510.         je      rpstap                  ; e = yes, do so
  2511.         ret                             ; No - must have been an echo
  2512.  
  2513. rpstat: mov     al,escape               ; Tell them we think we are OK
  2514.         call    prtbout
  2515.         mov     al,'['
  2516.         call    prtbout
  2517.         mov     al,'0'
  2518.         call    prtbout
  2519.         mov     al,'n'
  2520.         call    prtbout
  2521.         ret
  2522.  
  2523. rpstap: test    escdec,decmode          ; Printer status report from
  2524.         jz      rpstap3                 ; ESC [ ? 15 n  request
  2525.         mov     al,escape
  2526.         call    prtbout
  2527.         mov     al,'['
  2528.         call    prtbout
  2529.         mov     al,'?'
  2530.         call    prtbout
  2531.         mov     al,'1'
  2532.         call    prtbout
  2533.         mov     ah,ioctl                ; get printer status, via DOS
  2534.         mov     al,7                    ; status for output
  2535.         push    bx
  2536.         mov     bx,4                    ; std handle for system printer
  2537.         int     dos
  2538.         pop     bx
  2539.         jc      rpstap1                 ; c = call failed
  2540.         cmp     al,0ffh                 ; code for Ready
  2541.         jne     rpstap1                 ; ne = not ready
  2542.         mov     al,'0'                  ; ready, send final digit
  2543.         jmp     rpstap2
  2544. rpstap1:mov     al,'3'                  ; not ready, say printer disconnected
  2545. rpstap2:call    prtbout
  2546.         mov     al,'n'                  ; final char of response
  2547.         call    prtbout
  2548. rpstap3:ret
  2549.  
  2550. rpcup:  mov     al,escape               ; Cursor position - send an escape
  2551.         call    prtbout
  2552.         mov     al,'['                  ; And one of these
  2553.         call    prtbout
  2554.         mov     al,byte ptr cursor+1    ; Get row
  2555.         inc     al                      ; They use coords that start at 1
  2556.         test    ansflgs,decom           ; Origin mode set?
  2557.         jz      rpcup1                  ; No - continue
  2558.         sub     al,mar_top              ; Yes - subtract off top margin
  2559. rpcup1: call    prtnout                 ; Output the number
  2560.         mov     al,';'                  ; Separate
  2561.         call    prtbout
  2562.         mov     al,byte ptr cursor      ; Now get the column number
  2563.         inc     al                      ; Their coords start at 1
  2564.         call    prtnout                 ; Send it off to the port
  2565.         mov     al,'R'                  ; Finally end it with this
  2566.         call    prtbout
  2567.         ret
  2568.  
  2569.                                         ; ESC [ ? xxx h/l  series
  2570. atrm:   mov     modeset,0               ; Say we are resetting modes
  2571.         mov     di,offset atrsm         ; Reset/set modes
  2572.         call    atreps                  ; Repeat for all parms
  2573.         test    ansflgs,decanm          ; Did this get reset?
  2574.         jnz     atrm1                   ; No - return
  2575.         cmp     flags.vtflg,ttheath     ; were we a Heath-19?
  2576.         je      atrm0                   ; e = yes, don't change terminal types
  2577.         mov     flags.vtflg,ttvt52      ; Yes. Say VT52 now
  2578. atrm0:  call    chrdef                  ; Yes - set default char sets
  2579.         call    atsc                    ; Save cursor status
  2580.         call    disleds                 ; update terminal type
  2581. atrm1:  ret
  2582.  
  2583. atsm:   mov     modeset,1               ; Say we are setting modes
  2584.         mov     di,offset atrsm         ; Reset/set modes
  2585.         call    atreps                  ; Repeat for all parms
  2586.         ret
  2587.  
  2588. atrsm:  mov     al,ansargs[si]          ; Pick up the argument
  2589.         test    escdec,decmode          ; Is this DEC private mode ([ ?)stuff?
  2590.         jnz     atrsm1                  ; nz = yes - go check it out
  2591.         cmp     h19mod,0                ; Heath-19 private mode ([ >)?
  2592.         je      atrsma                  ; e = no
  2593.         jmp     htrsm1                  ; yes, do Heath specific things
  2594. atrsma: cmp     al,20                   ; No - ANSI new-line mode?
  2595.         jne     atrsm0                  ;  but try insert mode
  2596.         and     vtemu.vtflgop,not vsnewline ; assume resetting
  2597.         cmp     modeset,0               ; resetting?
  2598.         je      atrsmb                  ; e = yes
  2599.         or      vtemu.vtflgop,vsnewline ; setting
  2600. atrsmb: mov     al,anslnm               ; Yes - get the bit
  2601.         call    atrsflg                 ; Set or reset it
  2602.         ret
  2603. atrsm0: cmp     al,4                    ; toggle insert mode?
  2604.         jne     atrsmc                  ; ne = no
  2605.         mov     al,modeset              ; set/reset insert mode
  2606.         mov     insmod,al               ; store it
  2607.         ret
  2608. atrsmc: cmp     al,12                   ; 12? Control local echo
  2609.         jne     atrsmx                  ; ne = no
  2610.         cmp     modeset,0               ; resetting mode (ESC [ 12 l)?
  2611.         jne     atrsmc1                 ; ne = no
  2612.         or      ansflgs,dececho         ; remember state here too
  2613.         or      yflags,lclecho          ; (l) turn on local echoing
  2614.         jmp     short atrsmc2
  2615. atrsmc1:and     yflags,not lclecho      ; (h) turn off local echoing
  2616.         and     ansflgs,not dececho
  2617. atrsmc2:mov     al,yflags
  2618.         call    telmsy                  ; inform msy about echoing state
  2619.         test    yflags,modoff           ; is mode line off?
  2620.         jnz     atrsmx                  ; nz = yes
  2621.         push    dx                      ; save cursor position
  2622.         call    trnmod                  ; toggle off then on again so we
  2623.         call    trnmod                  ;   use it with current coloring
  2624.         pop     dx
  2625. atrsmx: ret
  2626.  
  2627. atrsm1: cmp     al,1                    ; Cursor keys mode?
  2628.         jne     atrsm2                  ; No - check some more
  2629.         mov     al,decckm               ; Yes - get the bit
  2630.         jmp     atrsflg                 ; Set or reset it and return
  2631.  
  2632. atrsm2: cmp     al,7                    ; Auto-wrap?
  2633.         jne     atrsm3                  ; No - check some more
  2634.         and     vtemu.vtflgop,not vswrap ; assume resetting line wrap
  2635.         cmp     modeset,0               ; resetting?
  2636.         je      atrsm2a                 ; e = yes
  2637.         or      vtemu.vtflgop,vswrap    ; set the bit
  2638. atrsm2a:mov     al,decawm               ; Yes - get the bit
  2639.         jmp     atrsflg                 ; Set or reset it and return
  2640.  
  2641. atrsm3: cmp     al,6                    ; Origin mode?
  2642.         jne     atrsm4                  ; No - check for video change
  2643.         jmp     atrsom                  ; Yes - change decom and return
  2644.  
  2645. atrsm4: cmp     al,5                    ; Change the video?
  2646.         jne     atrsm5                  ; No - check for VT52 mode set/reset
  2647.         jmp     atrsscnm                ; Yes - change it if we have to and ret
  2648.  
  2649. atrsm5: cmp     al,2                    ; Change VT52 compatibility mode?
  2650.         jne     atrsm6                  ; No - ignore unknown DEC private modes
  2651.         cmp     flags.vtflg,ttheath     ; Heath-19 mode?
  2652.         je      atrsm5a                 ; e = yes, handle specially
  2653.         mov     al,ascset               ; return to US ascii graphics sets
  2654.         mov     chr_sg0,al              ; Store it
  2655.         mov     chr_sg1,al              ; Store it
  2656.         mov     al,decanm               ; Yes - get the flag
  2657.         jmp     atrsflg                 ; Set or reset it and return
  2658.  
  2659. atrsm5a:mov     modeset,0               ; Heath-19 ESC [ ? 2 h, reset ansi
  2660.         mov     al,decanm               ; the flag needing adjustment
  2661.         jmp     atrsflg                 ; reset the flag and return
  2662.  
  2663. atrsm6: cmp     al,3                    ; 132/80 column mode change?
  2664.         jne     atrsm7                  ; ne = no
  2665.         push    chr_set                 ; save character set pointer
  2666.         push    word ptr chr_sg0        ; and the G0/G1 values
  2667.         mov     al,ansflgs              ; these flags
  2668.         mov     ah,vtflags
  2669.         push    ax
  2670.         mov     al,curattr              ; and current video attributes
  2671.         push    ax
  2672.         mov     al,modeset              ; pass set/reset request to chgdsp[dlk]
  2673.         call    chgdsp                  ; call Change Display proc in msy [dlk]
  2674.         call    scrmod                  ; get current screen mode
  2675.         cmp     modeset,1               ; want 132 cols?
  2676.         jne     atrsm6n                 ; ne = no, so use 80 columns
  2677.         mov     al,crt_cols             ; get current physical screen width
  2678.         dec     al                      ; we count from column 0 here
  2679.         mov     byte ptr low_rgt,al     ; screen capability
  2680.         mov     linelen,131             ; say using wide screen, if possible
  2681.         jmp     short atrsm6e
  2682. atrsm6n:mov     linelen,79              ; say using 80 columns
  2683.         cmp     byte ptr low_rgt,79     ; want 80 cols, is it wider?
  2684.         jbe     atrsm6e                 ; be = no
  2685.         mov     byte ptr low_rgt,79     ; narrow down to 80 columns
  2686. atrsm6e:CALL    ATRES2                  ; do partial reset of emulator
  2687.         pop     ax
  2688.         mov     curattr,al              ; restore saved items
  2689.         pop     ax
  2690.         mov     ansflgs,al
  2691.         mov     vtflags,ah
  2692.         pop     word ptr chr_sg0        ; restore the G0/G1 values
  2693.         pop     chr_set                 ; and character set pointer
  2694.         mov     dl,byte ptr low_rgt+1   ; text lines (leave status line intact)
  2695.         mov     mar_top,0
  2696.         mov     mar_bot,dl              ; reset scrolling region
  2697.         xor     dx,dx                   ; new cursor position is 0,0
  2698.         mov     cursor,dx
  2699.         jmp     atscu5                  ; place it there and return
  2700.  
  2701. atrsm7: cmp     al,18                   ; 18?  18 & 19 = printer support
  2702.         jne     atrsm8                  ; ne = no
  2703.         cmp     modeset,0               ; resetting?
  2704.         jne     atrsm7a                 ; ne = no, setting
  2705.         and     anspflg,not vtffp       ; no form feed after printing
  2706.         ret
  2707. atrsm7a:or      anspflg,vtffp           ; use form feed after printing
  2708.         ret
  2709.  
  2710. atrsm8: cmp     al,19                   ; 19?
  2711.         jne     atrsm9                  ; ne = no
  2712.         cmp     modeset,0               ; resetting?
  2713.         jne     atrsm8a                 ; ne = no, setting
  2714.         and     anspflg,not vtextp      ; reset print region to scrolling reg
  2715.         ret
  2716. atrsm8a:or      anspflg,vtextp          ; set print region to whole screen
  2717.         ret
  2718.  
  2719. atrsm9: cmp     al,34                   ; ESC [ ? 34 h/l? Invoke special macro
  2720.         jne     atrsm10                 ; ne = no
  2721.         cmp     modeset,0               ; resetting?
  2722.         jne     atrsm9a                 ; ne = no, setting
  2723.         jmp     vtrmac                  ; jump to perform on-line macro
  2724.                                         ;  code is located in file msy
  2725. atrsm9a:jmp     vtsmac                  ; do set macro
  2726.  
  2727. atrsm10:cmp     al,38                   ; 38? Enter Tek sub-mode. VT340 seq
  2728.         jne     atrsm11                 ; ne = no
  2729.         cmp     modeset,1               ; setting mode (ESC [ ? 38 h)?
  2730.         jne     atrsm11                 ; ne = no, ignore sequence
  2731.         test    denyflg,200h            ; is auto Tek mode disabled?
  2732.         jnz     atrsm11                 ; nz = yes, just ignore command
  2733.         call    atsc                    ; save cursor and associated data
  2734.         mov     al,0                    ; enter with this received character
  2735.         JMP     TEKEMU                  ; Jump to Tektronix Emulator, al=null
  2736.  
  2737. atrsm11:ret
  2738.                 ; Heath-19  ESC [ > Ps h or l where Ps = 1, 4, 7, or 9
  2739. htrsm1: cmp     al,1                    ; 25th line?
  2740.         jne     htrsm4                  ; ne = no
  2741.         mov     al,modeset              ; set/reset flag
  2742.         mov     h19l25,al
  2743.         cmp     al,0                    ; resetting? Mods from Dave Tweten
  2744.         jne     htrsmx                  ; ne = no, enabling. we are done
  2745.         mov     ah,byte ptr low_rgt+1   ; point to status (25th) line
  2746.         inc     ah                      ;  which is here
  2747.         xor     al,al                   ; from column 0
  2748.         mov     bh,ah                   ; to same line
  2749.         mov     bl,crt_cols             ; physical width
  2750.         dec     bl                      ; we count from 0
  2751.         jmp     vtsclr                  ; disabling status line clears it
  2752.  
  2753. htrsm4: cmp     al,4                    ; block/line cursor?
  2754.         jne     htrsm5                  ; ne = no
  2755.         and     h19ctyp,4               ; save on/off bit (4)
  2756.         cmp     modeset,0               ; reset?
  2757.         je      htrsm4a                 ; e = yes
  2758.         or      h19ctyp,2               ; remember block kind here
  2759.         jmp     atsctyp
  2760. htrsm4a:or      h19ctyp,1               ; remember underline kind here
  2761.         jmp     atsctyp
  2762.  
  2763. htrsm5: cmp     al,5                    ; on/off cursor?
  2764.         jne     htrsm7                  ; ne = no
  2765.         cmp     modeset,0               ; on?
  2766.         je      htrsm5a                 ; e = yes
  2767.         or      h19ctyp,4               ; remember off state in this bit
  2768.         jmp     atsctyp
  2769. htrsm5a:and     h19ctyp,not 4           ; set cursor on
  2770.         jmp     atsctyp
  2771.  
  2772. htrsm7: cmp     al,7                    ; alternate application keypad?
  2773.         jne     htrsm9                  ; ne = no
  2774.         mov     al,deckpam              ; get keypad application mode bit
  2775.         jmp     atrsflg                 ; set or reset appl keypad mode
  2776.  
  2777. htrsm9: cmp     al,9                    ; auto newline mode? (add cr to lf)
  2778.         jne     htrsmx                  ; ne = no
  2779.         mov     al,anslnm               ; get the bit
  2780.         jmp     atrsflg                 ; set or reset newline mode
  2781.  
  2782. htrsmx: ret                             ; ignore the code
  2783.  
  2784. atrsflg:cmp     modeset,0               ; Want to reset
  2785.         je      atrsf1                  ; Yes - reset it
  2786.         or      ansflgs,al              ; No, set. OR in the flag
  2787.         test    al,decanm               ; Changing terminal type?
  2788.         jz      atrsfx                  ; z = no
  2789.         cmp     flags.vtflg,ttheath     ; in Heath-19 mode?
  2790.         je      atrsfx                  ; e = yes, don't flip terminal kinds
  2791.         mov     flags.vtflg,ttvt100     ; say VT100 now
  2792.         jmp     short atrsfx
  2793. atrsf1: not     al                      ; Complement
  2794.         and     ansflgs,al              ; Clear the bit
  2795.         not     al                      ; recover the bit
  2796.         test    al,decanm               ; Changing terminal type?
  2797.         jz      atrsfx                  ; z = no
  2798.         cmp     flags.vtflg,ttheath     ; in Heath-19 mode?
  2799.         je      atrsfx                  ; e = yes, don't flip terminal kinds
  2800.         mov     flags.vtflg,ttvt52      ; say VT52 now
  2801. atrsfx: push    ax
  2802.         mov     al,yflags
  2803.         call    telmsy                  ; tell msy file about new state
  2804.         pop     ax
  2805.         ret
  2806.  
  2807. atrsom: cmp     modeset,0               ; Clearing DEC origin mode?
  2808.         jne     atrsom1                 ; ne = no, setting
  2809.         and     ansflgs,not (decom)     ; clear the bit
  2810.         mov     dx,0                    ; go to the home position
  2811.         jmp     atscu5                  ; set cursor and return
  2812. atrsom1:or      ansflgs,decom           ; Set Origin mode
  2813.         mov     dx,cursor               ; Get the cursor
  2814.         mov     dl,0                    ; go to right margin
  2815.         mov     dh,mar_top              ; go to home of scrolling region
  2816.         jmp     atscu5                  ; Set the cursor and return
  2817.  
  2818. atrsscnm:
  2819.         cmp     modeset,0               ; Setting or resetting?
  2820.         je      atrss1                  ; Do reset
  2821.         test    ansflgs,decscnm         ; Setting. Is it set already?
  2822.         jnz     atrss3                  ; Yes. Don't do it again
  2823.         or      ansflgs,decscnm         ; No. Set it
  2824.         or      vtemu.vtflgop,vsscreen  ; tell Status display
  2825.         or      vtflags,vsscreen        ; and our local flags
  2826.         mov     al,att_reverse          ; Want reverse video
  2827.         jmp     short atrss2            ; Do it
  2828.  
  2829. atrss1: test    ansflgs,decscnm         ; Resetting. Is it reset already?
  2830.         jz      atrss3                  ; Yes.  Don't do it again
  2831.         and     ansflgs,not decscnm     ; No. Clear it
  2832.         and     vtemu.vtflgop,not vsscreen      ; tell Status display
  2833.         and     vtflags,not vsscreen    ; and our local flags
  2834.         mov     al,att_normal           ; Want normal video
  2835.                                         ; Fall through to atrss2
  2836.  
  2837. ; Note: This is also called from the stblmds initialization routine.
  2838.  
  2839. atrss2: push    ax
  2840.         mov     scbattr,al              ; Set screen background attribute
  2841.         mov     oldbatr,al              ; update long term memory too
  2842.         mov     ah,al                   ; place where brkatt works
  2843.         call    brkatt                  ; separate color and specials
  2844.         rol     ah,1                    ; Reverse the reversal (sic.)
  2845.         rol     ah,1                    ; Reverse the reversal (sic.)
  2846.         rol     ah,1                    ; Reverse the reversal (sic.)
  2847.         rol     ah,1                    ; Reverse the reversal (sic.)
  2848.         call    addatt                  ; put blink/bold bits back in
  2849.         mov     mlbattr,ah              ; For mode line background
  2850.         mov     ah,curattr              ; Get current cursor attribute
  2851.         call    brkatt                  ; Break it up
  2852.         rol     ah,1                    ; Reverse its background
  2853.         rol     ah,1                    ; Reverse its background
  2854.         rol     ah,1                    ; Reverse its background
  2855.         rol     ah,1                    ; Reverse its background
  2856.         call    addatt                  ; Put it back together
  2857.         mov     curattr,ah              ; And store it
  2858.         pop     ax
  2859.         call    revscn                  ; Reverse everything on the screen
  2860. atrss3: ret
  2861.  
  2862.  
  2863. atctst: mov     al,0                    ; Init test weight
  2864.         mov     di,offset atcts2        ; Routine to call
  2865.         call    atreps                  ; Repeat for all parms
  2866.         test    al,80H                  ; Want to reset?
  2867.         jz      atcts1                  ; No - return
  2868.         call    atreset                 ; Yes - reset everything
  2869. atcts1: ret
  2870.  
  2871. atcts2: mov     ah,ansargs[si]          ; Pick up an argument
  2872.         cmp     ah,0                    ; Zero?
  2873.         jne     atcts3                  ; No - ignore others
  2874.         or      al,80H                  ; Yes - say we want reset
  2875. atcts3: ret
  2876.  
  2877.  
  2878. ; VT52 compatibility mode routines.
  2879.  
  2880. ; Return to ANSI mode.
  2881.  
  2882. v52ans: or      ansflgs,decanm          ; Turn ANSI flag back on
  2883.         mov     flags.vtflg,ttvt100     ; Say VT100 now
  2884.         call    chrdef                  ; Set default char sets
  2885.         call    atsc                    ; Save cursor status
  2886.         call    disleds                 ; Put "LEDs" back
  2887.         jmp     atnorm                  ; Reset state to normal and return
  2888.  
  2889. ; Reset VT52 (does NOT cause return to VT100 mode)
  2890.  
  2891. v52ris: call    atreset                 ; Reset everything
  2892.         call    disleds                 ; Put "LEDs" back
  2893.         ret
  2894.  
  2895. ; Enter VT52 "graphics" mode.
  2896.  
  2897. v52egm: call    chrsgs                  ; Set "graphics" char set
  2898.         jmp     atnorm                  ; Reset state to normal and return
  2899.  
  2900. ; Exit VT52 "graphics" mode.
  2901.  
  2902. v52xgm: call    chrdef                  ; Set default character set
  2903.         jmp     atnorm                  ; Reset state to normal and return
  2904.  
  2905. ; VT52 cursor positioning.
  2906.  
  2907. v52pos: mov     ttstate,offset v52pc1   ; Next state
  2908.         ret
  2909.  
  2910. v52pc1: sub     al,' '-1                ; Minus offset
  2911.         mov     ansargs,al              ; Stash it here
  2912.         mov     ttstate,offset v52pc2   ; Next state
  2913.         ret
  2914.  
  2915. v52pc2: sub     al,' '-1                ; Minus offset
  2916.         mov     ansargs+1,al            ; Stash here
  2917.         call    atnorm                  ; Reset state to "normal"
  2918.         jmp     atcup                   ; Position and return
  2919.  
  2920. ; VT52 print controls
  2921.  
  2922. v52apb: mov     ansargs,5               ; Enter auto print mode
  2923.         or      escdec,decmode          ; simulate ESC [ ? 5 i
  2924.         jmp     ansprt                  ; process command
  2925.  
  2926. v52ape: mov     ansargs,4               ; Exit auto print mode
  2927.         or      escdec,decmode          ; simulate ESC [ ? 4 i
  2928.         jmp     ansprt                  ; process command
  2929.  
  2930. v52pcb: mov     ansargs,5               ; Enter printer controller on
  2931.         or      escdec,decmode          ; simulate ESC [ ? 5 i
  2932.         jmp     ansprt                  ; process command
  2933.  
  2934. v52pce: mov     ansargs,4               ; Exit printer controller on
  2935.         or      escdec,decmode          ; simulate ESC [ ? 4 i
  2936.         jmp     ansprt                  ; process command
  2937.  
  2938. v52ps:  mov     ansargs,0               ; print screen
  2939.         and     escdec,not decmode      ; simulate ESC [ 0 i
  2940.         jmp     ansprt                  ; process command
  2941.  
  2942. v52pl:  mov     ansargs,1               ; print line
  2943.         or      escdec,decmode          ; simulate ESC [ ? 1 i
  2944.         jmp     ansprt                  ; process command
  2945.  
  2946.                                         ; Heath-19 special functions
  2947.  
  2948. h19ans: or      ansflgs,decanm          ; Turn on ANSI flag. ESC <
  2949.         call    chrdef                  ; Set default char sets
  2950.         jmp     atnorm                  ; Reset state to normal and return
  2951.  
  2952.                                         ; do several "ESC ["  ANSI commands
  2953.                                         ; but don't change terminal types
  2954. h19ansa:jmp     atcsi                   ; parse ansi arguments
  2955.  
  2956.                                         ; clear screen and go home
  2957. h19clrs:mov     dx,0                    ; go to upper left corner
  2958.         call    atscu5                  ; do it
  2959.         mov     ax,0                    ; clear screen from (0,0)
  2960.         mov     bh,byte ptr low_rgt+1   ; to lower right corner
  2961.         mov     bl,crt_cols             ; physical width
  2962.         dec     bl                      ; we count from 0
  2963.         jmp     vtsclr                  ; Clear it
  2964.                                         ; cursor down (scrolls)
  2965. h19cud: mov     dx,cursor               ; get cursor position
  2966.         inc     dh                      ; say next row down
  2967.         call    atccic                  ; check position cursor (scrolls)
  2968.         mov     cursor,dx
  2969.         call    ax                      ; do scrolling
  2970.         jmp     atscu5
  2971.                                         ; cursor forward (right). ESC C
  2972. h19cuf: mov     dx,cursor               ; get cursor position
  2973.         inc     dl                      ; move cursor right
  2974.         cmp     dl,byte ptr low_rgt     ; beyond right margin
  2975.         jb      h19cuf1                 ; b = no. do it
  2976.         test    ansflgs,decawm          ; wrap mode on?
  2977.         jz      h19cuf2                 ; z = no. just ignore movement
  2978.         xor     dl,dl                   ; set to left margin
  2979.         inc     dh                      ; and down a row
  2980.         call    atccic                  ; adjust position
  2981.         call    ax                      ; call scrolling routine
  2982. h19cuf1:jmp     atscu5                  ; do positioning and return
  2983. h19cuf2:ret                             ; just return
  2984.  
  2985.                                         ; set line wrap on
  2986. h19wrap:or      ansflgs,decawm          ; turn on the flag
  2987.         jmp     atnorm
  2988.  
  2989.                                         ; turn off line wrap
  2990. h19nowrp:and    ansflgs,not decawm      ; turn off the flag
  2991.         jmp     atnorm
  2992.  
  2993. h19erb: mov     bx,cursor               ; erase home to cursor, incl
  2994.         xor     ax,ax                   ; home
  2995.         jmp     vtsclr                  ; clear the area, cursor stays put???
  2996.  
  2997. h19erl: mov     bx,cursor               ; erase whole line
  2998.         mov     ax,bx                   ; get row
  2999.         xor     al,al                   ; column 0
  3000.         mov     bl,crt_cols             ; physical width
  3001.         dec     bl                      ; we count from 0
  3002.         jmp     vtsclr                  ; erase whole line, cursor stays put
  3003.  
  3004. h19ero: mov     bx,cursor               ; erase start of line to cursor
  3005.         mov     ax,bx
  3006.         xor     al,al                   ; start in column 0
  3007.         jmp     vtsclr                  ; clear that part of line
  3008.  
  3009. h19herv:cmp     video_state,0           ; is video normal? ESC p
  3010.         jne     h19hrv1                 ; ne = no, reversed already, ignore
  3011.         mov     ah,curattr              ; current cursor attributes
  3012.         call    brkatt                  ; breakup attributes byte
  3013.         rol     ah,1                    ; reverse foreground to background
  3014.         rol     ah,1
  3015.         rol     ah,1
  3016.         rol     ah,1
  3017.         call    addatt                  ; put things together again
  3018.         mov     curattr,ah              ; and store it
  3019.         mov     video_state,1           ; say we are reversed
  3020. h19hrv1:ret
  3021.  
  3022. h19hxrv:cmp     video_state,0           ; is video normal? ESC q
  3023.         je      h19hxr1                 ; e = yes, so just ignore
  3024.         mov     ah,curattr              ; current cursor attributes
  3025.         call    brkatt                  ; breakup attributes byte
  3026.         rol     ah,1                    ; reverse foreground to background
  3027.         rol     ah,1
  3028.         rol     ah,1
  3029.         rol     ah,1
  3030.         call    addatt                  ; put things together again
  3031.         mov     curattr,ah              ; and store it
  3032.         mov     video_state,0           ; say we are normal
  3033. h19hxr1:ret
  3034.  
  3035. h19mbr: mov     ttstate,offset hmbr     ; Modify baud rate ESC r char
  3036.         ret                             ; setup to parse next char
  3037. hmbr:   jmp     atnorm                  ; discard char (in al)
  3038.  
  3039. htsc:   cmp     flags.vtflg,ttheath     ; Heath-19? ESC [ s
  3040.         jne     htscx                   ; ne = no, ignore
  3041.         call    atsc                    ; store cursor position and attr
  3042. htscx:  jmp     atnorm                  ; reset state & return
  3043.  
  3044. htrc:   cmp     flags.vtflg,ttheath     ; Heath-19? ESC [ u
  3045.         jne     htrcx                   ; ne = no, ignore
  3046.         call    atrc                    ; restore cursor pos and attr
  3047. htrcx:  jmp     atnorm                  ; reset state & return
  3048.  
  3049.                                         ; Heath-19 set mode "ESC x "
  3050. h19smod:mov     ttstate,offset hsmod    ; setup to parse rest of seq
  3051.         ret
  3052.  
  3053. hsmod:  mov     modeset,1               ; say set mode
  3054.         mov     ttstate,offset atnrm
  3055.         sub     al,'0'                  ; remove ascii bias
  3056.         jmp     htrsm1                  ; perform mode set
  3057.  
  3058. h19cmod:mov     ttstate,offset hcmod    ; setup to parse rest of seq
  3059.         ret
  3060.  
  3061. hcmod:  mov     modeset,0               ; say reset mode
  3062.         mov     ttstate,offset atnrm
  3063.         sub     al,'0'                  ; remove ascii bias
  3064.         jmp     htrsm1                  ; perform mode reset
  3065.  
  3066. htrest: cmp     flags.vtflg,ttheath     ; Heath-19? ESC [ z
  3067.         jne     htrestx                 ; ne = no, ignore
  3068.         call    atreset                 ; do a hard reset
  3069. htrestx:jmp     atnorm                  ; reset state and return
  3070.  
  3071. hrcup:  mov     al,escape               ; send "ESC Y row col" cursor report
  3072.         call    prtbout                 ; send with no local echo
  3073.         mov     al,'Y'
  3074.         call    prtbout
  3075.         mov     al,byte ptr cursor+1    ; get row
  3076.         add     al,' '                  ; add ascii bias
  3077.         call    prtbout                 ; send it
  3078.         mov     al,byte ptr cursor      ; get column
  3079.         add     al,' '                  ; add ascii bias
  3080.         call    prtbout                 ; and send it too
  3081.         jmp     atnorm                  ; return to terminal mode
  3082.  
  3083.                                         ; Heath-19 and VT102 additions
  3084.  
  3085. inslin: cmp     ansargs,0               ; insert line(s). Any args?
  3086.         jne     insli1                  ; ne = yes. If no arg use 1
  3087.         mov     ansargs,1               ; insert one line
  3088. insli1: mov     dl,ansargs
  3089.         mov     scroll,dl
  3090.         mov     dx,cursor               ; current position
  3091.         cmp     dh,mar_bot              ; below bottom margin?
  3092.         jae     insli3                  ; ae = at or below bottom margin
  3093.         push    word ptr mar_top
  3094.         mov     mar_top,dh              ; call present position the top
  3095. insli2: call    atscrd                  ; scroll down
  3096.         pop     word ptr mar_top        ; restore margins
  3097.         xor     dl,dl                   ; go to left margin
  3098.         jmp     atscu5                  ; reposition cursor and return
  3099. insli3: ret
  3100.  
  3101. dellin: cmp     ansargs,0               ; delete line(s). Any args?
  3102.         jne     delli1                  ; no arg; use 1
  3103.         mov     ansargs,1               ; insert one line
  3104. delli1: mov     dl,ansargs
  3105.         mov     scroll,dl               ; line count
  3106.         mov     dx,cursor               ; where we are presently
  3107.         cmp     dh,mar_bot              ; at or below bottom margin?
  3108.         jae     delli3                  ; ae = yes
  3109.         push    word ptr mar_top        ; save current scrolling margins
  3110.         mov     mar_top,dh              ; temp top margin is here
  3111. delli2: call    atscru                  ; scroll up
  3112.         pop     word ptr mar_top        ; restore scrolling margins
  3113.         jmp     atscu5                  ; restore cursor and return
  3114. delli3: ret
  3115.  
  3116.                                         ; Delete character(s)
  3117. atdelc: cmp     ansargs,0               ; zero becomes one operation
  3118.         jne     atdelc1
  3119.         mov     ansargs,1               ; delete one char. Heath ESC N
  3120. atdelc1:mov     cl,byte ptr low_rgt     ; number of columns on screen
  3121.         mov     dx,cursor               ; get present cursor position
  3122.         push    bx
  3123.         mov     bl,dh                   ; get row
  3124.         mov     bh,0
  3125.         cmp     linetype [bx],0         ; single width line?
  3126.         je      atdelc5                 ; e = yes
  3127.         shl     dl,1                    ; double the column number
  3128.         mov     bl,ansargs
  3129.         shl     bl,1                    ; double # chars to delete
  3130.         mov     ansargs,bl
  3131. atdelc5:pop     bx
  3132.         sub     cl,dl                   ; end of screen - current column #
  3133.         xor     ch,ch                   ; cx = number of chars to move
  3134.         cmp     cx,0                    ; zero means just this char
  3135.         ja      atdelc4
  3136.         inc     cx                      ; say one, this one
  3137. atdelc4:push    es
  3138.         push    cx                      ; save word count for Topview
  3139.         cld
  3140.         test    vtemu.vtflgop,vswdir    ; writing left to right?
  3141.         jz      atdelc4a                ; z = yes
  3142.         sub     dl,byte ptr low_rgt     ; reflect about logical right column
  3143.         neg     dl                      ; convert to positive value
  3144. atdelc4a:
  3145.         call    scrloc                  ; compute current cursor location
  3146.         mov     di,ax                   ; temporary storage places
  3147.         mov     si,ax
  3148.         mov     al,ansargs              ; get delete count
  3149.         xor     ah,ah                   ; clear high byte of delete count
  3150.         cmp     al,cl                   ; clear more than rest of line?
  3151.         jb      atdelc2                 ; b = no. some chars left at end
  3152.         mov     al,cl                   ; say delete all to right, inclusive
  3153. atdelc2:cmp     al,0                    ; zero?
  3154.         jne     atdelc3
  3155.         inc     al                      ; none or 0 implies one
  3156. atdelc3:shl     ax,1                    ; double: char and its attribute byte
  3157.         push    di                      ; destination offset
  3158.         cld                             ; assume forward for left to right
  3159.         test    vtemu.vtflgop,vswdir    ; writing left to right
  3160.         jz      atdelc3a                ; z = yes
  3161.         neg     ax                      ; minus ax, work the other way
  3162.         std                             ; movement reverses too
  3163. atdelc3a:
  3164.         add     ax,si                   ; src offset = dest + # deleted words
  3165.         push    ax                      ; save it
  3166.         call    scroff
  3167.         call    scrseg                  ; pick up screen segment
  3168.         mov     si,di                   ; align memory addresses
  3169.         pop     ax                      ; recover source offset
  3170.         add     si,ax                   ; add to starting memory address
  3171.         pop     ax                      ; recover destination offset
  3172.         add     di,ax                   ; add to destination memory address
  3173.         push    ds                      ; save ds around the move
  3174.         push    es                      ; move es into ds to
  3175.         pop     ds                      ; make ds point to screen memory too
  3176.         rep     movsw
  3177.         cld                             ; reset direction to forward
  3178.         pop     ds                      ; recover normal ds
  3179.         pop     cx                      ; count for Topview
  3180.         test    vtemu.vtflgop,vswdir    ; writing left to right?
  3181.         jz      atdelc6                 ; z = yes
  3182.         sub     di,cx                   ; get correct es:di ending address
  3183.         sub     di,cx                   ; for scrsync
  3184. atdelc6:call    scrsync                 ; synch Topview
  3185.         pop     es
  3186.         call    scron
  3187.         mov     ax,cursor               ; get current row
  3188.         mov     bx,cursor
  3189.         mov     bl,byte ptr low_rgt     ; last col on screen
  3190.         mov     al,bl
  3191.         sub     al,ansargs              ; minus number of locations cleared
  3192.         inc     al
  3193.         test    vtemu.vtflgop,vswdir    ; writing left to right?
  3194.         jz      atdelc7                 ; z = yes
  3195.         mov     cl,byte ptr low_rgt     ; reflect about logical right margin
  3196.         sub     cl,al
  3197.         mov     bl,cl                   ; end of line to be cleared
  3198.         mov     al,0                    ; start of line to be cleared
  3199. atdelc7:call    atsclr                  ; clear end of line
  3200. atdelcx:mov     dx,cursor
  3201.         jmp     atscu5                  ; reposition cursor
  3202.  
  3203. inschr: mov     dx,cursor               ; open one char space in current line
  3204.         push    bx
  3205.         mov     bl,dh                   ; get row
  3206.         mov     bh,0
  3207.         cmp     linetype [bx],0         ; single width line?
  3208.         je      insch2                  ; e = yes
  3209.         shl     dl,1                    ; double the column number
  3210. insch2: pop     bx
  3211.         mov     ch,0
  3212.         mov     cl,byte ptr low_rgt     ; number of columns on screen
  3213.         push    dx
  3214.         mov     dh,0
  3215.         sub     cx,dx                   ; compute distance to end
  3216.         pop     dx
  3217.         or      cx,cx
  3218.         jle     insch1                  ; le = nothing to move [dlk]
  3219.         mov     dl,byte ptr low_rgt
  3220.         dec     dl                      ; last col to move
  3221.         push    ax                      ; save regs
  3222.         push    es                      ; ditto
  3223.         push    cx                      ; save count for Topview
  3224.         test    vtemu.vtflgop,vswdir    ; writing left to right?
  3225.         jz      insch3                  ; z = yes
  3226.         mov     dl,1                    ; right-to-left physical EOL-1
  3227.         call    scrloc                  ; compute position of end of line-1
  3228.         push    ax                      ; save offset
  3229.         cld                             ; remember to move forward
  3230.         call    scroff                  ; turn off color screen
  3231.         call    scrseg                  ; get memory address in es:di
  3232.         pop     ax                      ; recover offset
  3233.         add     di,ax                   ; source memory address
  3234.         mov     si,di                   ; align addresses. destination
  3235.         sub     di,2                    ;   is one char over
  3236.         jmp short insch4                ; join common code
  3237. insch3:                                 ; do normal left to right material
  3238.         call    scrloc                  ; compute position of end of line-1
  3239.         push    ax                      ; save offset
  3240.         std                             ; remember to move backward
  3241.         call    scroff                  ; turn off color screen
  3242.         call    scrseg                  ; get memory address in es:di
  3243.         pop     ax                      ; recover offset
  3244.         add     di,ax                   ; source memory address
  3245.         mov     si,di                   ; align addresses. destination
  3246.         add     di,2                    ;   is one char over
  3247. insch4: push    di
  3248.         push    ds                      ; save ds around move
  3249.         push    es                      ; put es into ds
  3250.         pop     ds                      ;   ds points to screen memory too
  3251.         rep     movsw
  3252.         pop     ds                      ; recover normal ds
  3253.         cld                             ; reset direction to be forward
  3254.         pop     di
  3255.         pop     cx                      ; count for Topview
  3256.         test    vtemu.vtflgop,vswdir    ; writing left to right?
  3257.         jz      insch5                  ; z = yes
  3258.         add     di,cx                   ; get correct es:di ending address
  3259.         add     di,cx                   ; for scrsync
  3260. insch5: call    scrsync                 ; synch Topview
  3261.         pop     es                      ; restore regs
  3262.         pop     ax                      ; ditto
  3263.         call    scron                   ; turn on screen again
  3264.         cld                             ; reset direction
  3265. insch1: mov     dx,cursor
  3266.         jmp     atscu5                  ; position cursor
  3267.  
  3268. noins:  mov     insmod,0                ; turn off insert mode
  3269.         jmp     atnorm                  ; and return
  3270.  
  3271. entins: mov     insmod,0ffh             ; enter insert mode
  3272.         jmp     atnorm                  ; and return
  3273.  
  3274. ansich  proc    near                    ; ANSI insert characters ESC [ Pn @
  3275.         cmp     ansargs,0               ; any arguments?
  3276.         jne     ansic1                  ; ne = no, ignore
  3277.         mov     ansargs,1               ; use one
  3278. ansic1: push    dx                      ; save cursor
  3279.         mov     insmod,1                ; enter insert mode
  3280.         push    cx
  3281.         mov     cl,ansargs              ; get count of inserts
  3282.         mov     ch,0
  3283.         mov     ah,ansflgs              ; save flags in ah
  3284.         and     ansflgs,not decawm      ; turn off autowrap
  3285.         push    ax                      ; save char
  3286. ansic2: push    cx                      ; save counter
  3287.         mov     al,' '                  ; character to write
  3288.         call    atnrm                   ; do display
  3289.         pop     cx                      ; recover counter
  3290.         loop    ansic2                  ; do cx times
  3291.         pop     ax                      ; restore char
  3292.         mov     ansflgs,ah              ; recover flags
  3293.         mov     ah,0                    ; clear register
  3294.         pop     cx
  3295.         mov     insmod,0                ; turn off insert mode
  3296.         pop     dx                      ; get original cursor
  3297.         jmp     atscu5                  ; set cursor
  3298. ansich  endp
  3299.  
  3300. ; routines supporting scrolling and double width/height chars
  3301. ; scroll has number of lines to scroll
  3302. atscru  proc    near                    ; scroll screen up one line
  3303.         push    ax                      ; assumes dx holds cursor position
  3304.         push    bx                      ; returns with dx = old row, new col
  3305.         push    cx
  3306.         push    si
  3307.         xor     bh,bh
  3308.         mov     bl,mar_top              ; top line to move
  3309.         xor     ch,ch
  3310.         mov     cl,scroll               ; number of lines to move
  3311.         jcxz    atscru5                 ; cx = 0. nothing to do
  3312.         mov     al,mar_bot              ; bottom line to scroll
  3313.         sub     al,bl                   ; number of lines minus 1
  3314.         inc     al                      ; number of lines
  3315.         cmp     al,cl                   ; scrolling region smaller than scroll?
  3316.         jge     atscru1                 ; ge = no, is ok
  3317.         mov     scroll,al               ; limit to region
  3318.         cmp     al,1                    ; at least one line to scroll?
  3319.         jge     atscru1                 ; ge = yes
  3320.         mov     scroll,1                ; no, force one
  3321. atscru1:push    bx
  3322.         mov     bl,dh                   ; get row of cursor
  3323.         mov     bh,0
  3324.         cmp     linetype[bx],0          ; single width?
  3325.         pop     bx
  3326.         je      atscru7                 ; e = yes
  3327.         shr     dl,1                    ; reindex to single width columns
  3328. atscru7:mov     al,scroll
  3329.         xor     ah,ah
  3330.         cmp     al,byte ptr low_rgt+1   ; number of lines on screen
  3331.         jbe     atscru8                 ; be = scrolling not more than that
  3332.         mov     al,byte ptr low_rgt+1   ; limit to screen length
  3333.         mov     scroll,al
  3334. atscru8:mov     si,ax                   ; scroll interval
  3335.         mov     bl,mar_top
  3336.         mov     cl,mar_bot
  3337.         sub     cl,bl
  3338.         inc     cl                      ; number  of lines in region
  3339.         sub     cl,scroll               ; cx = those needing movement
  3340.         jcxz    atscru3
  3341. atscru2:mov     al,linetype[bx+si]      ; get old type
  3342.         mov     linetype[bx],al         ; copy to new higher position
  3343.         inc     bx
  3344.         loop    atscru2
  3345. atscru3:mov     bl,mar_bot              ; set fresh lines to single attribute
  3346.         mov     cl,scroll
  3347.         mov     ch,0
  3348.         inc     cx
  3349. atscru4:mov     linetype[bx],0
  3350.         dec     bx
  3351.         loop    atscru4                 ; clear old bottom lines
  3352. atscru5:pop     si
  3353.         pop     cx
  3354.         pop     bx
  3355.         pop     ax
  3356.         test    anspflg,vtcntp          ; controller print active?
  3357.         jz      atscru6                 ; z = no, ok to change screen
  3358.         ret                             ;  else keep screen intact
  3359. atscru6:jmp     vtscru                  ; call & ret the msy scroll routine
  3360. atscru  endp
  3361.  
  3362. atscrd  proc    near                    ; scroll screen down one line
  3363.         push    ax                      ; assumes dx holds cursor position
  3364.         push    bx                      ; returns with dx = old row, new col
  3365.         push    cx
  3366.         push    si
  3367.         xor     ch,ch
  3368.         mov     cl,scroll               ; number of lines to scroll
  3369.         jcxz    atscrd5                 ; cx = 0. nothing to do
  3370.         xor     bh,bh
  3371.         mov     bl,mar_bot              ; bottom line to move
  3372.         mov     al,bl
  3373.         mov     ah,0
  3374.         sub     al,mar_top              ; number of lines minus 1
  3375.         inc     al                      ; number of lines
  3376.         cmp     al,cl                   ; scrolling region smaller than scroll?
  3377.         jge     atscrd1                 ; ge = no, is ok
  3378.         mov     scroll,al               ; limit to region
  3379.         cmp     al,1                    ; at least one line to scroll?
  3380.         jge     atscrd1                 ; ge = yes
  3381.         mov     scroll,1                ; no, force one
  3382. atscrd1:push    bx
  3383.         mov     bl,dh                   ; get row of cursor
  3384.         mov     bh,0
  3385.         cmp     linetype[bx],0          ; single width?
  3386.         pop     bx
  3387.         je      atscrd7                 ; e = yes
  3388.         shr     dl,1                    ; reindex to single wide columns
  3389. atscrd7:mov     al,scroll
  3390.         mov     si,ax                   ; si = scroll
  3391.         sub     bl,scroll               ; si + this bx will be new bottom line
  3392.         mov     cl,bl
  3393.         sub     cl,mar_top
  3394.         inc     cl                      ; number of movements
  3395.         jcxz    atscrd3
  3396. atscrd2:mov     al,linetype[bx]         ; get old line's type
  3397.         mov     linetype[bx+si],al      ; copy to new lower position
  3398.         dec     bx
  3399.         loop    atscrd2
  3400. atscrd3:mov     bl,mar_top
  3401.         mov     bh,0
  3402.         mov     cl,scroll
  3403.         mov     ch,0
  3404.         inc     cx
  3405. atscrd4:mov     linetype[bx],0          ; clear new top lines
  3406.         inc     bx
  3407.         loop    atscrd4
  3408. atscrd5:pop     si
  3409.         pop     cx
  3410.         pop     bx
  3411.         pop     ax
  3412.         test    anspflg,vtcntp          ; controller print active?
  3413.         jz      atscrd6                 ; z = no, ok to change screen
  3414.         ret                             ;  else keep screen intact
  3415. atscrd6:jmp     vtscrd                  ; call & ret the msy scroll routine
  3416. atscrd  endp
  3417.  
  3418. linesgl proc    near                    ; convert line to single width char
  3419.         push    ax
  3420.         push    bx
  3421.         push    cx
  3422.         push    dx
  3423.         mov     bx,cursor
  3424.         mov     bl,bh
  3425.         xor     bh,bh                   ; bx now holds row
  3426.         cmp     linetype [bx],0         ; is line already single width?
  3427.         je      linsglx                 ; e = yes
  3428.         mov     linetype [bx],0         ; say will be single now
  3429.         call    scroff                  ; turn off video
  3430.         mov     dx,cursor
  3431.         mov     dl,0                    ; start in column 0
  3432.         mov     cl,byte ptr low_rgt     ; number of columns on screen
  3433.         inc     cl
  3434.         shr     cl,1                    ; number of columns to do
  3435.         mov     ch,0
  3436.         push    cx                      ; save around loop below
  3437. linsgl1:push    cx                      ; save loop counter
  3438.         shl     dl,1                    ; double column number
  3439.         mov     ah,2                    ; set cursor
  3440.         xor     bh,bh                   ; page 0
  3441.         call    direction               ; do Bios screen operation
  3442.         mov     ah,8                    ; read char and attribute
  3443.         int     screen
  3444.         push    ax                      ; save char and attribute
  3445.         shr     dl,1                    ; restore column
  3446.         mov     ah,2                    ; set cursor
  3447.         call    direction               ; do Bios screen operation
  3448.         pop     ax                      ; recover char and attribute
  3449.         mov     bl,ah                   ; set attribute
  3450.         mov     cx,1                    ; one char
  3451.         mov     ah,9                    ; write char and attribute
  3452.         int     screen
  3453.         inc     dl                      ; next column
  3454.         pop     cx
  3455.         loop    linsgl1
  3456.         pop     cx                      ; recover column counter
  3457.         mov     dl,cl
  3458. linsgl2:push    cx                      ; save counter
  3459.         mov     ah,2                    ; set cursor
  3460.         call    direction               ; do Bios screen operation
  3461.         mov     bh,0
  3462.         mov     bl,scbattr              ; screen background
  3463.         mov     al,' '
  3464.         mov     ah,9                    ; write char
  3465.         mov     cx,1                    ; do one character
  3466.         call    direction               ; do Bios screen operation
  3467.         inc     dl                      ; next column
  3468.         pop     cx
  3469.         loop    linsgl2                 ; repeat for all characters
  3470.         call    scron                   ; turn on the video
  3471. linsglx:pop     dx
  3472.         pop     cx
  3473.         pop     bx
  3474.         pop     ax
  3475.         jmp     atscur                  ; update cursor and return
  3476. linesgl endp
  3477.  
  3478. linedbl proc    near                    ; convert line to double width char
  3479.         push    ax                      ; must reset physical cursor
  3480.         push    bx                      ; to same char as before expansion
  3481.         push    cx                      ; but does not modify variable cursor
  3482.         push    dx
  3483.         mov     bx,cursor
  3484.         mov     bl,bh
  3485.         xor     bh,bh                   ; bx now holds row
  3486.         cmp     linetype [bx],0         ; is line single width?
  3487.         jne     lindblx                 ; ne = no. nothing to do
  3488.         mov     linetype [bx],1         ; say will be double width now
  3489.         mov     dx,cursor
  3490.         mov     cl,byte ptr low_rgt     ; number of columns on the screen
  3491.         inc     cl
  3492.         mov     ch,0
  3493.         shr     cl,1                    ; number of items to do
  3494.         mov     dl,cl
  3495.         dec     dl
  3496.         call    scroff                  ; turn off the video
  3497. lindbl1:push    cx                      ; save loop counter
  3498.         mov     ah,2                    ; set cursor
  3499.         mov     bh,0                    ; page 0
  3500.         call    direction               ; do Bios screen operation
  3501.         mov     ah,8                    ; read char and attribute
  3502.         int     screen
  3503.         push    ax                      ; save char and attribute
  3504.         shl     dl,1                    ; double the column number
  3505.         mov     ah,2                    ; set cursor
  3506.         call    direction               ; do Bios screen operation
  3507.         pop     ax                      ; recover char and attribute
  3508.         mov     bl,ah                   ; set attribute
  3509.         mov     cx,1                    ; one char
  3510.         mov     ah,9                    ; write char and attribute
  3511.         int     screen
  3512.         inc     dl                      ; move to second column of double
  3513.         mov     ah,2                    ; set cursor
  3514.         call    direction               ; do Bios screen operation
  3515.         mov     al,' '                  ; space as filler
  3516.         mov     ah,9                    ; write that char
  3517.         int     screen
  3518.         dec     dl
  3519.         shr     dl,1
  3520.         dec     dl
  3521.         pop     cx
  3522.         loop    lindbl1
  3523.         call    scron                   ; turn on the video
  3524. lindblx:pop     dx
  3525.         pop     cx
  3526.         pop     bx
  3527.         pop     ax
  3528.         jmp     atscur                  ; update the cursor and return
  3529. linedbl endp
  3530.  
  3531. anstty  endp
  3532.  
  3533. ansprt  proc near                       ; printer support routines
  3534.         mov     di,offset ansprt0       ; routine to process arguments
  3535.         call    atreps                  ; Repeat for all parms
  3536.         ret
  3537.  
  3538. ansprt0:mov     ah,ansargs[si]          ; Pick up the argument
  3539.         cmp     ah,0                    ; 0 (print all/part of screen)?
  3540.         jne     ansprt1                 ; ne = no
  3541.         call    pntchk                  ; check printer
  3542.         jc      ansprtx                 ; c = printer not ready
  3543.         call    pntext                  ; do whole screen or scrolling extent
  3544.         jmp     atscu5                  ; reposition cursor and return
  3545.  
  3546. ansprt1:cmp     ah,1                    ; 1 (print current line)?
  3547.         jne     ansprt4                 ; ne = no
  3548.         call    pntchk                  ; check for printer ready
  3549.         jc      ansprtx                 ; c = printer not ready
  3550.         call    pntlin                  ; print current line
  3551.         call    pntflsh                 ; flush printer buffer
  3552. anspr1a:jmp     atscu5                  ; reposition cursor and return
  3553.  
  3554. ansprt4:cmp     ah,4                    ; 4 (auto print disable)?
  3555.         jne     ansprt5                 ; ne = no
  3556.         test    escdec,decmode          ; was it ESC [ ? 4 i
  3557.         jz      anspr4a                 ; z = no, so it was ESC [ 4 i
  3558.         test    anspflg,vtautop         ; check state of print flag
  3559.         jz      anspr4a                 ; z = off already
  3560.         and     anspflg,not vtautop     ; auto-print disable
  3561.         call    trnprs                  ; toggle mode line PRN indicator
  3562. anspr4a:jmp     ansprtx
  3563.  
  3564. ansprt5:cmp     ah,5                    ; 5 (auto print enable)?
  3565.         jne     ansprtx                 ; ne = no
  3566.         call    pntchk                  ; check printer, ignore carry ret
  3567.         jc      ansprtx                 ; c = printer not ready
  3568.         test    escdec,decmode          ; was it ESC [ ? 5 i
  3569.         jz      anspr5a                 ; z = no
  3570.         test    anspflg,vtautop         ; is print already enabled?
  3571.         jnz     ansprtx                 ; nz = yes, leave trnprs intact
  3572.         or      anspflg,vtautop         ; auto-print enabled
  3573.         jmp     short anspr5b
  3574. anspr5a:test    anspflg,vtcntp          ; controller print already enabled?
  3575.         jnz     ansprtx                 ; nz = yes
  3576.         or      anspflg,vtcntp          ; controller print enabled
  3577. anspr5b:call    trnprs                  ; toggle on mode line PRN indicator
  3578. ansprtx:jmp     atnorm
  3579. ansprt  endp
  3580.  
  3581. ; State machine active while Media Copy On (Print Controller ON). Copies all
  3582. ; chars to the printer until (and excluding) Media Copy Off (ESC [ 4 i) has
  3583. ; been received or the emulator reset. New char is in al. 6 March 1987 [jrd]
  3584.  
  3585. ansmc   proc    near
  3586.         mov     ah,al                   ; copy active character
  3587.         and     ah,7fh                  ; strip high bit
  3588.         cmp     ah,escape               ; start of MC Off sequence?
  3589.         jne     ansmc1                  ; ne = no
  3590.         call    ansmc6                  ; playback previously matched chars
  3591.         mov     mccnt,1                 ; count matched chars (one now)
  3592.         mov     mcoffs,al               ; save full character, with high bit
  3593.         mov     ansargs,0               ; clear first ansi argument
  3594.         mov     nansarg,0               ; number of arguments
  3595.         ret
  3596.  
  3597. ansmc1: mov     bx,mccnt                ; number of chars matched in MC Off
  3598.         cmp     bx,0                    ; have first?
  3599.         jne     ansmc1a                 ; ne = yes, one or more
  3600.         jmp     pntchr                  ; print it, ignore errors
  3601.  
  3602. ansmc1a:mov     mcoffs[bx],al           ; save this char, with high bit
  3603.         inc     mccnt                   ; count saved characters
  3604.         and     al,7fh                  ; strip high bit
  3605.         cmp     al,'0'                  ; A digit?
  3606.         jge     ansmc2                  ; ge = maybe
  3607.         jmp     ansmc6                  ; b = out of range for everything
  3608. ansmc2: cmp     al,'9'                  ; maybe, separator or final char?
  3609.         ja      ansmc3                  ; a = perhaps, go check it out
  3610.         mov     cl,al                   ; digit, convert ASCII to binary
  3611.         sub     cl,'0'
  3612.         mov     ch,0
  3613.         mov     bl,nansarg              ; put index in bx
  3614.         xor     bh,bh
  3615.         mov     al,ansargs[bx]          ; Pick up what we've done so far [dlk]
  3616.         shl     al,1                    ; multiply by 10.  2 * al
  3617.         mov     ah,al                   ; save
  3618.         shl     al,1                    ; 4 * al
  3619.         shl     al,1                    ; 8 * al
  3620.         add     al,ah                   ; 10 * al
  3621.         mov     ah,0                    ; clear high field
  3622.         add     ax,cx                   ; add in this digit [dlk]
  3623.         cmp     ax,0feh                 ; max value is 0ffh [dlk]
  3624.         jbe     ansmc2a                 ; be = ok [dlk]
  3625.         mov     al,0ffh                 ; set to max value [dlk]
  3626. ansmc2a:mov     ansargs[bx],al          ; Put result back for next time [dlk]
  3627.         ret                             ; And return
  3628.  
  3629. ansmc3: cmp     al,'['                  ; ANSI sequence?
  3630.         jne     ansmc4                  ; ne = no, check further
  3631.         cmp     mccnt,2                 ; is it the second character?
  3632.         je      ansmc3a                 ; e = yes, accept and continue
  3633.         jmp     ansmc6                  ; no, end match
  3634. ansmc3a:ret                             ; continue
  3635.  
  3636. ansmc4: cmp     al,';'                  ; Argument separator?
  3637.         jne     ansmc5                  ; ne = no, check for final char
  3638.         inc     nansarg                 ; yes, count it
  3639.         mov     bl,nansarg              ; get argument index
  3640.         mov     bh,0
  3641.         mov     ansargs[bx],0           ; clear next arg field
  3642.         cmp     bl,lansarg              ; too many?
  3643.         jl      ansmc4a                 ; l = no, continue
  3644.         dec     nansarg                 ; yes, do not add more
  3645.         jmp     ansmc6                  ; end match now
  3646. ansmc4a:ret                             ; accept separator and continue
  3647.  
  3648. ansmc5: cmp     al,'i'                  ; sequence terminator?
  3649.         jne     ansmc6                  ; ne = no, end match
  3650.         mov     bx,-1
  3651.         mov     cl,nansarg              ; number of argument values
  3652.         mov     ch,0
  3653.         inc     cx                      ; no args is same as one
  3654. ansmc5a:inc     bx
  3655.         mov     al,ansargs[bx]          ; get ansi argument
  3656.         mov     ansargs[bx],0ffh        ; and zap it to absorb early values
  3657.         cmp     al,4                    ; MC OFF value?
  3658.         loopne  ansmc5a                 ; ne = no, examine all non-matches
  3659.         jne     ansmc6                  ; ne = no match, end matching
  3660.                                         ; MC OFF sequence discovered
  3661.         mov     mccnt,0                 ; clear counter
  3662.         call    pntflsh                 ; flush printer buffer
  3663.         test    anspflg,vtcntp          ; was printing active?
  3664.         jz      ansmc5b                 ; z = no, do nothing
  3665.         and     anspflg,not vtcntp      ; yes, disable print controller
  3666.         call    trnprs                  ; toggle mode line PRN indicator
  3667. ansmc5b:jmp     ansprt                  ;  done, process arguments in order
  3668.  
  3669.                                         ; MC OFF sequence not found, playback
  3670. ansmc6: push    ax                      ; save break char (in al)
  3671.         push    cx                      ; playback partial sequence to printer
  3672.         mov     cx,mccnt                ; number of chars matched before break
  3673.         jcxz    ansmc6b                 ; z = none
  3674.         push    si
  3675.         mov     si,offset mcoffs        ; string to be played back
  3676.         cld
  3677. ansmc6a:lodsb                           ; get a char into al
  3678.         call    pntchr                  ; print it, ignore errors
  3679.         loop    ansmc6a                 ; do all that came in previously
  3680.         pop     si
  3681. ansmc6b:pop     cx
  3682.         pop     ax                      ; recover break char
  3683.         mov     mccnt,0                 ; reset to no match and exit
  3684.         mov     nansarg,0
  3685.         ret
  3686. ansmc   endp
  3687.  
  3688. pntlin  proc    near                    ; print whole line given by dx
  3689.         push    ax
  3690.         push    bx
  3691.         push    cx
  3692.         push    dx
  3693.         xor     ch,ch
  3694.         mov     cl,byte ptr low_rgt     ; number of columns
  3695.         mov     dl,cl                   ; Bios column counter, dh = row
  3696.         inc     cl                      ; actual line length, count it down
  3697.         test    vtemu.vtflgop,vswdir    ; writing right to left?
  3698.         jnz     pntlin2                 ; nz = yes, do not trim spaces
  3699. pntlin1:mov     ah,2                    ; set cursor
  3700.         xor     bh,bh                   ; page 0
  3701.         int     screen
  3702.         mov     ah,8                    ; read char (al) and attribute (ah)
  3703.         int     screen
  3704.         cmp     al,' '                  ; is this a space?
  3705.         jne     pntlin2                 ; no, we have the end of the line
  3706.         dec     dl                      ; else move left one column
  3707.         loop    pntlin1                 ; and keep looking for non-space
  3708.  
  3709. pntlin2:jcxz    pntlin4                 ; z = empty line
  3710.         xor     dl,dl                   ; start in column 0, do cl chars
  3711. pntlin3:mov     ah,2                    ; set cursor
  3712.         xor     bh,bh                   ; page 0
  3713.         int     screen
  3714.         mov     ah,8                    ; read char and attribute
  3715.         int     screen
  3716.         inc     dl                      ; inc to next column
  3717.         call    pntchr                  ; print the char (in al)
  3718.         jc      pntlin5                 ; c = printer error
  3719.         loop    pntlin3                 ; do cx columns
  3720. pntlin4:mov     al,cr                   ; add trailing cr/lf for printer
  3721.         call    pntchr
  3722.         jc      pntlin5
  3723.         mov     al,lf
  3724.         call    pntchr
  3725. pntlin5:pop     dx
  3726.         pop     cx
  3727.         pop     bx
  3728.         pop     ax
  3729.         ret                             ; C bit controlled by pntchr
  3730. pntlin  endp
  3731.  
  3732. pntext  proc    near                    ; print an extent of lines, depending
  3733.         push    ax                      ; on flag bit vtextp
  3734.         push    bx
  3735.         push    dx
  3736.         xor     dx,dx                   ; assume starting at top left
  3737.         mov     bx,low_rgt              ;  and extending to lower right
  3738.         test    anspflg,vtextp          ; full screen wanted?
  3739.         jnz     pntext1                 ; nz = yes, else scrolling region
  3740.         mov     dh,mar_top              ; top of scrolling region
  3741.         mov     bh,mar_bot              ; bottom of scrolling region
  3742. pntext1:call    pntlin                  ; print a line
  3743.         jc      pntext2                 ; c = printer error
  3744.         inc     dh
  3745.         cmp     dh,bh                   ; done all requested lines?
  3746.         jbe     pntext1                 ; be = not yet, do another
  3747.         test    anspflg,vtffp           ; form feed needed at end?
  3748.         jz      pntext2                 ; z = no
  3749.         mov     al,ff
  3750.         call    pntchr                  ; print the form feed char
  3751. pntext2:pop     dx
  3752.         pop     bx
  3753.         pop     ax
  3754.         ret
  3755. pntext  endp
  3756.  
  3757. ; Do Bios screen operation with consideration for writing direction.
  3758. ; Enter with normal registers set, preserves register dx.
  3759.  
  3760. direction proc  near
  3761.         push    dx
  3762.         test    vtemu.vtflgop,vswdir    ; writing left to right?
  3763.         jz      direct1                 ; z = yes, do Bios function
  3764.         sub     dl,byte ptr low_rgt     ; right margin column number
  3765.         neg     dl                      ; make a positive value again
  3766. direct1:int     screen
  3767.         pop     dx
  3768.         ret
  3769. direction endp
  3770.  
  3771. ; Clear screen from AX to BX, where AH = row, AL = column, ditto for BX.
  3772. ; This routine accomodates right to left writing. BX >= AX.
  3773. vtsclr  proc    near
  3774.         test    vtemu.vtflgop,vswdir    ; writing left to right?
  3775.         jz      vtsclr4                 ; z = yes
  3776.         cmp     bh,ah                   ; same row?
  3777.         je      vtsclr2                 ; e = yes
  3778.         push    ax                      ; multiple lines
  3779.         push    bx                      ; save both coordinates
  3780.         mov     bl,byte ptr low_rgt     ; get right most logical column
  3781.         mov     bh,ah                   ; pick just top line
  3782.         call    vtsclr2                 ; delete fraction of top line
  3783.         pop     bx                      ; recover ending position
  3784.         push    bx
  3785.         inc     ah                      ; omit top row, now done
  3786.         dec     bh                      ; omit last line, could be fractional
  3787.         cmp     bh,ah                   ; any whole lines remaining to delete?
  3788.         jb      vtsclr1                 ; b = no, finish up
  3789.         mov     bl,byte ptr low_rgt     ; get right most physical column
  3790.         mov     al,0                    ; to end of line (on left)
  3791.         call    atsclr                  ; clear top line and whole remainders
  3792. vtsclr1:pop     bx                      ; setup for last line to be cleared
  3793.         push    bx                      ; get last row again
  3794.         mov     al,0                    ; start at logical left margin
  3795.         jmp     short vtsclr3           ; ax and bx are already pushed
  3796.  
  3797. vtsclr2:push    ax                      ; erase single line, whole or part
  3798.         push    bx
  3799. vtsclr3:mov     ah,byte ptr low_rgt     ; borrow reg ah (same as bh)
  3800.         sub     ah,bl                   ; reflect right to left
  3801.         mov     bl,ah
  3802.         or      bl,bl                   ; overflow?
  3803.         jns     vtsclr5                 ; ns = no, is ok
  3804.         mov     bl,0                    ; limit to logical screen
  3805. vtsclr5:mov     ah,byte ptr low_rgt
  3806.         sub     ah,al
  3807.         mov     al,ah
  3808.         jns     vtsclr6
  3809.         mov     al,byte ptr low_rgt     ; limit to logical screen
  3810. vtsclr6:mov     ah,bh                   ; restore ah
  3811.         xchg    al,bl                   ; reverse to get physical ax < bx
  3812.         call    atsclr                  ; erase part/all of single line
  3813.         pop     bx
  3814.         pop     ax
  3815.         ret
  3816.                                         ; for writing left to right
  3817. vtsclr4:jmp     atsclr                  ; do normal erasure and return
  3818. vtsclr  endp
  3819.  
  3820.  
  3821. code    ends
  3822.  
  3823. if1
  3824.         %out [End of pass 1]
  3825. else
  3826.         %out [End of assembly]
  3827. endif
  3828.  
  3829.         end
  3830.